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 }
View Code

 

posted on 2016-03-22 22:06  onlyRP  阅读(154)  评论(0编辑  收藏  举报