45pts WA求助,大样例错一个-1
查看原帖
45pts WA求助,大样例错一个-1
341764
Hazet楼主2021/11/30 13:16
#include<bits/stdc++.h>

#define int __int128
#define mem(x,y) memset(x,y,sizeof(x))
#define frein freopen("in.in","r",stdin)
#define freout freopen("out.out","w",stdout)
#define debug(x) cout << (#x) << " = " << x << endl;

using namespace std;

int read(){
   int s = 0,w = 1;
   char ch = getchar();
   while(ch < '0' || ch > '9'){if(ch == '-')w = -1;ch = getchar();}
   while(ch >= '0' && ch <= '9')s = s * 10 + ch - '0',ch = getchar();
   return s * w;
}

mt19937 rnd(time(0));

struct FHQ_Treap{
	
	struct node{
		int l;
		int r;
		int w;
		int key;
		int siz;
	}e[1000010];
	
	int cnt,rt;
	
	void clear(){
		mem(e,0);
		cnt = rt = 0;
	}
	
	int newnode(int w){
		cnt ++;
		e[cnt].w = w;
		e[cnt].key = rnd();
		e[cnt].siz = 1;
		return cnt; 
	}
	
	void update(int i){
		e[i].siz = e[e[i].l].siz + e[e[i].r].siz + 1;
	}
	
	void split(int i,int w,int &x,int &y){
		if(!i){
			x = y = 0;
			return ;
		}
		if(e[i].w <= w){
			x = i;
			split(e[i].r,w,e[i].r,y);
		}
		else {
			y = i;
			split(e[i].l,w,x,e[i].l);
		}
		update(i);
	}
	
	int merge(int x,int y){
		if(!x || !y)return x + y;
		if(e[x].key > e[y].key){
			e[x].r = merge(e[x].r,y);
			update(x);
			return x;
		}
		else {
			e[y].l = merge(x,e[y].l);
			update(y);
			return y;
		}
	}
	
	void ins(int w){
		int x,y;
		split(rt,w,x,y);
		rt = merge(merge(x,newnode(w)),y);
	}
	
	void del(int w){
		int x,y,z;
		split(rt,w,x,z);
		split(x,w - 1,x,y);
		y = merge(e[y].l,e[y].r);
		rt = merge(merge(x,y),z);
	}
	
	int pre(int w){
		int x,y;
		split(rt,w - 1,x,y);
		int now = x;
		while(e[now].r)now = e[now].r;
		int ans = e[now].w;
		rt = merge(x,y);
		return ans;
	}
	
	int getmin(){
		int now = rt;
		while(e[now].l)now = e[now].l;
		return e[now].w;
	}
}t;

void exgcd(int a,int b,int &x,int &y){
	if(!b){
		x = 1;
		y = 0;
		return ;
	}
	exgcd(b,a % b,x,y);
	int tmp = x;
	x = y;
	y = tmp - a / b * y;
}

void write(int x){
	if(x < 0)x = -x,putchar('-');
	if(x > 9)write(x / 10);
	putchar(x % 10 + '0');
}

int lcm(int x,int y){return x / __gcd(x,y) * y;}

int tt;
int n,m;
int p[1000010];
int pri[1000010];

int k[1000010];
int yu[1000010];
int mod[1000010];
int nowyu,nowmod;
int ans;
int lcmm;
int minn;

int upper_get(int x,int y){return (x + y - 1) / y;}

void solve(){
	minn = -1e18;
	lcmm = 1;
	t.clear();
	n = read(),m = read();
	for(int i = 1;i <= n;i ++)yu[i] = read();
	for(int i = 1;i <= n;i ++)mod[i] = read();
	for(int i = 1;i <= n;i ++)pri[i] = read();
	for(int i = 1;i <= m;i ++)t.ins(read());
	for(int i = 1;i <= n;i ++){
		int v = t.getmin();
		if(v >= yu[i]){
			k[i] = v;
			t.del(v);
		}
		else {
			v = t.pre(yu[i]);
			k[i] = v;
			t.del(v);
		}
		t.ins(pri[i]);
	}
	for(int i = 1;i <= n;i ++)minn = max(minn,upper_get(yu[i],k[i]));
	for(int i = 1;i <= n;i ++){
		int xx,yy;
		if(i == 1){
			nowyu = yu[i];
			nowmod = mod[i];
			int kkksc03 = __gcd(k[i],mod[i]);
			if(yu[i] % kkksc03){
				puts("-1");
				return ;
			}
			exgcd(k[i],mod[i],xx,yy);
			ans = xx / kkksc03 * yu[i];
			nowyu = ans % nowmod;
			continue;
		}
		exgcd(k[i] * nowmod,mod[i],xx,yy);
		int gcdd = __gcd(k[i] * nowmod,mod[i]);
		int s = yu[i] - k[i] * nowyu;
		if(s % gcdd){
			puts("-1");
			return ;
		}
		xx = xx * (s / gcdd) % mod[i];
		ans = nowmod * xx + nowyu;
		nowmod = lcm(nowmod,mod[i]);
		ans %= nowmod;
		nowyu = ans;
	}
	ans = (ans % nowmod + nowmod) % nowmod;
	int add = minn - ans;
	lcmm = nowmod;
	if(add <= 0){
		write(ans);
		putchar('\n');
	}
	else {
		ans += lcmm * (add / lcmm);
		if(ans < minn)ans += lcmm;
		write(ans);
		putchar('\n');
	}
}

signed main(){
	frein;
	freout;
	tt = read();
	while(tt --)solve();
}

大概是excrt的问题

不太理解

2021/11/30 13:16
加载中...