取模自然溢出 WA on #27 求调
查看原帖
取模自然溢出 WA on #27 求调
765961
YL_billow楼主2024/11/18 20:33

rt

#define int unsigned 试过了还是 WA

换成 long long 然后对 2642^{64} 取模在 #2929 TLE 了。

本地拍出来挂掉的一组:

输入:

1 
3147446279 
18 
R 0 2638912245 
Q 0 0 7 
I 0 1719448131 
R 0 2090922890 
I 2 1571562356 
R 2 2064820829 
Q 0 0 7 
Q 0 2 9 
I 2 380945775 
D 2 
Q 2 2 8 
Q 0 0 10 
R 2 3811670563 
Q 0 1 4 
Q 0 0 5 
I 0 1744933748 
D 3 
D 2

正确答案:

2638912245
2090922890
3187116545
2064820829
2090922890
1363845850
2090922890

输出:

2638912245
2090922890
299294090
2064820829
2090922890
1363845850
2090922890

同一段代码连续运行几次,有些时候是对的,有些时候是错的。Windows 和 Linux 都试过了。不排除是 time(0) 的原因,但是固定种子交上去还是同一个点 WA 了。

感觉是自然溢出的时候爆掉了,但是自然溢出我不是很熟,不知道哪里写得不对。

代码

#include<bits/stdc++.h>
using namespace std;
namespace IO
{
	inline char read(char& x){x=getchar();while(x<'!') x=getchar();return x;}
	template<typename T> inline T read(T& x)
	{
		char ch=getchar();x=0;
		while(ch<'0'||ch>'9') ch=getchar();
		while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
		return x;
	}
	template<typename T,typename... Args> inline void read(T& x,Args&... args){read(x);read(args...);}
	template<typename T> void print(const T x){if(x>9) print(x/10);putchar(x%10^48);}
}using namespace IO;
typedef unsigned int uint;

const int N=1e5+5;
int n,m;uint a[N];

uint qp[N<<1][15];
uint inv[15][15];

struct AWA
{
	uint res[15];int len;
	inline AWA operator +(const AWA &x)const
	{
		AWA tmp;tmp.len=len+x.len;
		for(int i=0;i<=10;++i)
		{
			tmp.res[i]=res[i]; 
			for(int j=0;j<=i;++j) tmp.res[i]+=inv[i][j]*qp[len][i-j]*x.res[j];
		}
		return tmp;
	}
	inline AWA operator +(const int &x)const
	{
		AWA tmp;
		for(int i=0;i<=10;++i) tmp.res[i]=res[i]+x*qp[len+1][i];
		tmp.len=len+1;
		return tmp;
	}
	inline AWA& operator =(const uint &x){for(int i=0;i<=10;++i) res[i]=x;len=1;return *this;}
};

inline AWA operator +(const int &x,const AWA &y)
{
	AWA tmp;
	for(int i=0;i<=10;++i){tmp.res[i]=x;for(int j=0;j<=i;++j) tmp.res[i]+=inv[i][j]*y.res[j];}
	tmp.len=y.len+1;
	return tmp;
}

struct TREE{int ls,rs,siz,yl;AWA val;uint pri;}tree[N<<1];
int cnt,root;
#define ls(x) tree[x].ls
#define rs(x) tree[x].rs
inline void push_up(int x)
{
	const int l=ls(x),r=rs(x);
	tree[x].siz=tree[l].siz+tree[r].siz+1;
	if(l&&r) tree[x].val=(tree[l].val+tree[x].pri)+tree[r].val;
	else if(l) tree[x].val=tree[l].val+tree[x].pri;
	else if(r) tree[x].val=tree[x].pri+tree[r].val;
	else tree[x].val=tree[x].pri;
}
void split(const int x,const int p,int& L,int& R)
{
	if(!x){L=R=0;return ;}
	if(tree[ls(x)].siz>=p) R=x,split(ls(x),p,L,ls(x));
	else L=x,split(rs(x),p-tree[ls(x)].siz-1,rs(x),R);
	push_up(x); 
}
int merge(const int L,const int R)
{
	if(!L||!R) return L|R;
	if(tree[L].yl<tree[R].yl){rs(L)=merge(rs(L),R);push_up(L);return L;}
	else{ls(R)=merge(L,ls(R));push_up(R);return R;}
}

mt19937 yunluo(time(0));
inline int newnode(const uint k)
{
	tree[++cnt].pri=k;
	tree[cnt].val=k;
	tree[cnt].siz=1;
	tree[cnt].yl=yunluo();
	return cnt;
}
inline void insert(const int pos,const uint k)
{
	int L,R;
	split(root,pos-1,L,R);
	root=merge(merge(L,newnode(k)),R);
}
inline void delnum(const int pos)
{
	int L,M,R;
	split(root,pos,L,R);
	split(L,pos-1,L,M);
	M=merge(ls(M),rs(M));
	root=merge(merge(L,M),R);
}
inline uint query(const int l,const int r,const int k)
{
	int L,M,R;
	split(root,r,L,R);split(L,l-1,L,M);
	uint res=tree[M].val.res[k];
	root=merge(merge(L,M),R);
	return res;
}
void modify(const int x,const int pos,const uint k)
{
	if(tree[ls(x)].siz+1==pos) tree[x].pri=k;
	else if(tree[ls(x)].siz>=pos) modify(ls(x),pos,k);
	else modify(rs(x),pos-tree[ls(x)].siz-1,k);
	push_up(x);
}
#define mid ((l+r)>>1)
int build(const int l,const int r)
{
	if(l>r) return 0;
	if(l==r) return newnode(a[l]);
	const int x=newnode(a[mid]);
	ls(x)=build(l,mid-1);rs(x)=build(mid+1,r);
	push_up(x);return x;
}
#undef ls
#undef rs
#undef mid

int main()
{
	read(n);for(int i=1;i<=n;++i) read(a[i]);
	
	for(int i=1;i<=(n<<1);++i){qp[i][0]=1;for(int j=1;j<=10;++j) qp[i][j]=qp[i][j-1]*i;}
	for(int i=0;i<=10;++i){inv[i][0]=1;for(int j=1;j<=i;++j) inv[i][j]=inv[i][j-1]*(i-j+1)/j;}
	
	root=build(1,n);
	
	read(m);
	char opt;uint x,y,k;
	for(int i=1;i<=m;++i)
	    switch(read(opt))
		{
			case 'I':{read(x,y);insert(x+1,y);break;}
			case 'D':{read(x);delnum(x+1);break;}
			case 'R':{read(x,y);modify(root,x+1,y);break;}
			case 'Q':{read(x,y,k);print(query(x+1,y+1,k));putchar('\n');break;}
		}
	
	return 0;
}

调了很久了 awa,感谢帮忙所有调题的大佬。

2024/11/18 20:33
加载中...