不懂继续问
  • 板块学术版
  • 楼主HotDogSeller
  • 当前回复12
  • 已保存回复12
  • 发布时间2022/8/5 20:49
  • 上次更新2023/10/27 16:50:11
查看原帖
不懂继续问
540822
HotDogSeller楼主2022/8/5 20:49

还是原来的问题,会RE,随机数也改成mt生成了,可是,它没用。

代码如下:

#pragma GCC optimize(3)

#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<queue>
#include<set>
#include<cmath>
#include<memory.h>
#include<map>
#include<iomanip>
#include<random>
#include<stack>

#define int long long
#define INF 0x7fffffff
#define mod 998244353

using namespace std;

inline int read() {
    bool op=1;
	char ch;
    
	while((ch=getchar())<'0'||ch>'9'){
        if(ch=='-'){
        	op*=-1;
		} 
    }
    
    int num=ch-'0';
    while((ch=getchar())>='0'&&ch<='9') {
        num=num*10+ch-'0';
    }
    
    return op?num:-num;
}

struct node{
	int l,r;
	int lc,rc;
	int delta;
	int sum;
};

struct operation{
	int l;
	int r;
	int x;
};

std::mt19937 ran(249);

int n,q,opt,l,r,x,t;
int arr[200005];
vector<node> tree;//这个线段树计算的是每个数增加了多少 
vector<operation> op;
vector<int> v;

int itd=0;//指向当前进行到第几次修改之后(只要没查到我们就不做)
//当前指向操作不执行 

node make_node(int a,int b){
	node lre;
	lre.l=a;
	lre.r=b;
	return lre;
}

operation make_op(int a,int b,int c){
	operation lre;
	lre.l=a;
	lre.r=b;
	lre.x=c;
	return lre;
}

int len(int x){
	return tree[x].r-tree[x].l+1;
}

void build(int left,int right,int x){
	
	tree[x].delta=0;
	tree[x].l=left;
	tree[x].r=right;
	
	if(left==right){
		tree[x].sum=arr[tree[x].l];
	//	cout<<"x="<<x<<" left="<<left<<" right="<<right<<" sum="<<tree[x].sum<<endl;
		return;
	}
	
	int mid=left+right>>1;
	
	tree[x].lc=tree.size();
	tree.push_back(make_node(left,mid));
	build(left,mid,tree[x].lc);
	
	tree[x].rc=tree.size();
	tree.push_back(make_node(mid+1,right));
	build(mid+1,right,tree[x].rc);
	
	tree[x].sum=tree[tree[x].lc].sum+tree[tree[x].rc].sum;
	tree[x].sum%=mod;
	
//	cout<<"x="<<x<<" left="<<left<<" right="<<right<<" sum="<<tree[x].sum<<endl;
	
}

void push_up(int x){
	int l=tree[x].lc,r=tree[x].rc;
	tree[x].sum=tree[l].sum+tree[r].sum+tree[l].delta*len(l)+tree[r].delta*len(r);
	tree[x].sum%=mod;
}

void push_down(int x){
	int l=tree[x].lc,r=tree[x].rc;
	tree[l].delta=(tree[x].delta+tree[l].delta)%mod;
	tree[r].delta=(tree[x].delta+tree[r].delta)%mod;
	tree[x].delta=0;
	push_up(x);
}

void change(int x,int left,int right,int num){

	if(left<=tree[x].l&&tree[x].r<=right){
		tree[x].delta+=num;
		return;
	}
	
	int mid=tree[x].l+tree[x].r>>1;
	
	if(left<=mid){
		change(tree[x].lc,left,right,num);
	}
	if(right>mid){
		change(tree[x].rc,left,right,num);
	}
	
	push_up(x);
	
}

int query(int x,int left,int right){
	
//	cout<<"x="<<x<<" left="<<tree[x].l<<" right="<<tree[x].r;
//	cout<<" delta="<<tree[x].delta;
//	cout<<" sum="<<tree[x].sum<<endl;
	
	if(tree[x].l==tree[x].r){
		//cout<<"GET!"<<endl;
		return tree[x].sum+tree[x].delta*len(x);
	}
	
	int mid=tree[x].l+tree[x].r>>1;
	int lre=0;
	
	push_down(x);
	
	if(left<=mid){
		lre+=query(tree[x].lc,left,right);
	}
	if(right>mid){
		lre+=query(tree[x].rc,left,right);
	}
	
	push_down(x);
	
	return lre;
}

signed main(){
	
	srand(293);
	
	cin>>n>>q;
	
	freopen("time2.in","w",stdout);
	
	cout<<n<<" "<<q<<endl;
	
	for(int i=1;i<=n;i++){
		arr[i]=ran()%mod;
		cout<<arr[i]<<" ";
	}
	cout<<endl;
	
	tree.push_back(make_node(1,n));
	build(1,n,0);
	
	while(q--){
		
		opt=ran()%2+1;
		cout<<opt<<" ";
		
		if(opt==1){
			
			do{
				l=ran()%n+1;
			}while(l==n);
			
				r=ran()%(n-l)+l;
				x=ran()%mod;
			
			cout<<l<<" "<<r<<" "<<x<<" ";
			
			op.push_back(make_op(l,r,x));
		}else if(opt==2){
			
			l=ran()%n+1;
			r=ran()%(n-l)+l;
			
			t=ran()%3+1;
			
			cout<<l<<" "<<r<<" "<<t<<" ";
			
			if(op.size()==0){
				v.push_back(arr[x]);
				continue;
			}
			int aim=op.size()-t;//查询到第几次操作前,对应op坐标
			//当前指向操作不执行
			 
			if(itd<aim){
				for(int i=itd;i<aim;i++){
					change(0,op[i].l,op[i].r,op[i].x);
				}
				//cout<<"Forward!"<<endl;
			}else if(aim<itd){
				for(int i=itd-1;i>=aim;i--){
					change(0,op[i].l,op[i].r,(-1)*op[i].x);
				}
				//cout<<"Back!"<<endl;
			}
			
			itd=aim;
			v.push_back(query(0,l,r));
			
		}
		
		cout<<endl;
		
	}
	
	fclose(stdout);
	freopen("time2.out","w",stdout);
	for(int i=0;i<v.size();i++){
		cout<<v[i]<<endl;
	}
	fclose(stdout);
	
	return 0;
}
2022/8/5 20:49
加载中...