Too Naive!以为市选有多简单QAQ
用树套树,体验到了用朴素做法的妙处
先建一颗朴素的权值线段树,对树上的每个结点依次建线段树,表示区间上的权值的个数
写得挺艰难。。而且KPM+的几组数我过不去(orzKPM
1 #include<bits/stdc++.h> 2 #define inc(i,l,r) for(int i=l;i<=r;i++) 3 #define dec(i,l,r) for(int i=l;i>=r;i--) 4 #define link(x) for(edge *j=h[x];j;j=j->next) 5 #define mem(a) memset(a,0,sizeof(a)) 6 #define inf 1e9 7 #define ll long long 8 #define succ(x) (1<<x) 9 #define lowbit(x) (x&(-x)) 10 #define M 20000050 11 #define NM 50005 12 using namespace std; 13 int read(){ 14 int x=0,f=1;char ch=getchar(); 15 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 16 while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); 17 return x*f; 18 } 19 ll s[M]; 20 int tag[M],l[M],r[M],root[NM<<4],tot; 21 int n,m,_x,_y,_t; 22 ll query(int i,int x,int y){ 23 int t=x+y>>1; 24 if(!i||y<_x||_y<x)return 0; 25 if(_x<=x&&y<=_y)return s[i]; 26 return query(l[i],x,t)+query(r[i],t+1,y)+(min(y,_y)-max(x,_x)+1)*tag[i]; 27 } 28 void ask(){ 29 int l=1,r=n*2; 30 for(int k=1;l<r;){ 31 int t=l+r>>1;ll v=query(root[k<<1],1,n); 32 if(_t<=v)r=t,k<<=1;else _t-=v,l=t+1,k=k<<1|1; 33 } 34 printf("%d\n",n-l+1); 35 } 36 void mod(int &i,int x,int y){ 37 int t=x+y>>1; 38 if(y<_x||_y<x)return; 39 if(!i)i=++tot; 40 if(_x<=x&&y<=_y){ 41 s[i]+=y-x+1;tag[i]++;return; 42 } 43 mod(l[i],x,t);mod(r[i],t+1,y); 44 s[i]=s[l[i]]+s[r[i]]+(y-x+1)*tag[i]; 45 } 46 void upd(){ 47 int k=1; 48 for(int l=1,r=n*2;l<r;){ 49 int t=l+r>>1; 50 mod(root[k],1,n); 51 if(_t<=t)k=k<<1,r=t;else k=k<<1|1,l=t+1; 52 } 53 mod(root[k],1,n); 54 } 55 int main(){ 56 freopen("data.in","r",stdin); 57 freopen("test.out","w",stdout); 58 n=read();m=read(); 59 while(m--){ 60 int opt=read();_x=read();_y=read();_t=read(); 61 if(opt==1)_t=n-_t+1,upd(); 62 else ask(); 63 } 64 // printf("%d\n",tot); 65 }