bzoj 3343: 教主的魔法

这个的修改直接是对于块开一个数组,记录修改的值就好了,,,(像不像标记永久化??(2333,不知道从哪里掏出来的词))

都是很朴素的分块

 1 #include<bits/stdc++.h>
 2 #define N 1000005
 3 #define LL long long
 4 #define inf 0x3f3f3f3f
 5 using namespace std;
 6 inline int ra()
 7 {
 8     int x=0,f=1; char ch=getchar();
 9     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
10     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
11     return x*f;
12 }
13 int block,m,n,Q;
14 int add[N],sot[N],a[N],pos[N];
15 int find(int i, int w)
16 {
17     int l=(i-1)*block+1,r=min(i*block,n),orz=r;
18 //    for (int j=l; j<=r; j++) printf("%d  ",sot[j]+add[i]);
19     if (l==r) return sot[l]+add[i]>=w;
20     while (l<r)
21     {
22         int mid=l+r>>1;
23         if (add[i]+sot[mid]>=w) r=mid;
24         else l=mid+1;
25     }
26     if (l==orz) return (sot[l]+add[i]>=w);
27     else return orz-l+1;
28 }
29 int ask(int l, int r, int w)
30 {
31     int ans=0;
32     if (pos[l]==pos[r]){
33         for (int i=l; i<=r; i++)
34             if (add[pos[l]]+a[i]>=w) ans++;
35     }
36     else{
37         for (int i=l; i<=pos[l]*block; i++) if (add[pos[l]]+a[i]>=w) ans++;
38         for (int i=(pos[r]-1)*block+1; i<=r; i++) if (add[pos[r]]+a[i]>=w) ans++;
39     //    cout<<ans;
40         for (int i=pos[l]+1; i<pos[r]; i++)
41             ans+=find(i,w);
42     }
43     return ans;
44 }
45 void change(int l, int r, int w)
46 {
47     if (pos[l]==pos[r]){
48         for (int i=l; i<=r; i++) a[i]+=w;
49         for (int i=(pos[l]-1)*block+1; i<=pos[l]*block; i++)
50             sot[i]=a[i];
51         sort(sot+(pos[l]-1)*block+1,sot+pos[l]*block+1);
52     }
53     else {
54         for (int i=l; i<=pos[l]*block; i++) a[i]+=w;
55         for (int i=(pos[l]-1)*block+1; i<=pos[l]*block; i++) sot[i]=a[i];
56         sort(sot+(pos[l]-1)*block+1,sot+pos[l]*block+1);
57         for (int i=(pos[r]-1)*block+1; i<=r; i++) a[i]+=w;
58         for (int i=(pos[r]-1)*block+1; i<=pos[r]*block; i++) sot[i]=a[i];
59         sort(sot+(pos[r]-1)*block+1,sot+pos[r]*block+1);
60         for (int i=pos[l]+1; i<pos[r]; i++) add[i]+=w;
61     }
62 }
63 int main()
64 {
65     n=ra(); Q=ra();
66     block=sqrt(n); m=n/block+(n%block!=0);
67     for (int i=1; i<=n; i++)
68         a[i]=ra(),pos[i]=(i-1)/block+1,sot[i]=a[i];
69     for (int i=1; i<=m; i++)
70     {
71         int l=(i-1)*block+1,r=min(n,i*block);
72         sort(sot+l,sot+r+1);
73     }
74     while (Q--)
75     {
76         char s[3]; scanf("%s",s); int x=ra(),y=ra(),w=ra();
77         if (s[0]=='M') change(x,y,w);
78         else printf("%d\n",ask(x,y,w));
79 //        for (int i=1; i<=n; i++) printf("%d ",a[i]+add[pos[i]]); cout<<endl;
80     }
81     return 0;
82 }

 

posted @ 2017-02-23 21:29  ws_ccd  阅读(177)  评论(0编辑  收藏  举报