Lucky Array Codeforces - 121E

http://codeforces.com/contest/121/problem/E

话说这题貌似暴力可A啊。。。

正解是想出来了,结果重构代码,调了不知道多久才A

错误记录:

1.线段树搞混num(节点编号)和l(区间端点)

2.之前的dfs没有分离,写的非常混乱,迫不得已重构代码

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<vector>
  5 using namespace std;
  6 #define fi first
  7 #define se second
  8 #define mp make_pair
  9 #define pb push_back
 10 typedef long long ll;
 11 typedef unsigned long long ull;
 12 typedef pair<int,int> pii;
 13 #define N 100000
 14 int data[80]={4,7,44,47,74,77,444,447,474,477,744,747,774,777,
 15 4444,4447,4474,4477,4744,4747,4774,4777,7444,7447,7474,7477,
 16 7744,7747,7774,7777};
 17 bool ok[10010];
 18 int sd=30;
 19 int n,m;
 20 int d[N+100];
 21 vector<pii> qq;
 22 //d[i]表示满足data[j]>(i位置的实际值)的最小j
 23 //线段树中查询出的位置的值表示data[d[i]]-(i位置的实际值)
 24 namespace S
 25 {
 26 #define mid (l+((r-l)>>1))
 27 #define lc (num<<1)
 28 #define rc (num<<1|1)
 29 int minn[4*N],sum[4*N],delv[4*N];
 30 void pd(int num)
 31 {
 32     minn[lc]-=delv[num];minn[rc]-=delv[num];
 33     delv[lc]+=delv[num];delv[rc]+=delv[num];
 34     delv[num]=0;
 35 }
 36 void delx(int L,int R,int x,int l,int r,int num)
 37 {
 38     if(L<=l&&r<=R)
 39     {
 40         minn[num]-=x;delv[num]+=x;
 41         return;
 42     }
 43     pd(num);
 44     if(L<=mid)    delx(L,R,x,l,mid,lc);
 45     if(mid<R)    delx(L,R,x,mid+1,r,rc);
 46     minn[num]=min(minn[lc],minn[rc]);
 47 }
 48 void setx(int L,int x,int l,int r,int num)
 49 {
 50     if(l==r)    {minn[num]=x;return;}
 51     pd(num);
 52     if(L<=mid)    setx(L,x,l,mid,lc);
 53     else    setx(L,x,mid+1,r,rc);
 54     minn[num]=min(minn[lc],minn[rc]);
 55 }
 56 void setsum(int L,int x,int l,int r,int num)
 57 {
 58     if(l==r)    {sum[num]=x;return;}
 59     if(L<=mid)    setsum(L,x,l,mid,lc);
 60     else    setsum(L,x,mid+1,r,rc);
 61     sum[num]=sum[lc]+sum[rc];
 62 }
 63 void update(int l,int r,int num)
 64 {
 65     if(minn[num]>0)    return;
 66     if(l==r)    {qq.pb(mp(l,data[d[l]]-minn[num]));return;}//minn[l]->minn[num]
 67     pd(num);
 68     update(l,mid,lc);update(mid+1,r,rc);
 69     minn[num]=min(minn[lc],minn[rc]);
 70 }
 71 int gsum(int L,int R,int l,int r,int num)
 72 {
 73     if(L<=l&&r<=R)    return sum[num];
 74     int ans=0;
 75     if(L<=mid)    ans+=gsum(L,R,l,mid,lc);
 76     if(mid<R)    ans+=gsum(L,R,mid+1,r,rc);
 77     return ans;
 78 }
 79 void work()
 80 {
 81     for(auto pp:qq)
 82     {
 83         int &l=pp.fi,&d=pp.se;
 84         int p=upper_bound(data,data+sd,d)-data;
 85         setx(l,data[p]-d,1,n,1);
 86         setsum(l,ok[d],1,n,1);
 87         ::d[l]=p;
 88     }
 89     qq.clear();
 90 }
 91 }
 92 char tmp[10];
 93 int main()
 94 {
 95     int i,t,L,R,x;
 96     for(i=0;i<sd;i++)    ok[data[i]]=1;
 97     for(i=0;i<sd;i++)    data[i+sd]=data[i]+1;
 98     sd*=2;sort(data,data+sd);
 99     data[sd++]=12000;
100     scanf("%d%d",&n,&m);
101     for(i=1;i<=n;i++)    scanf("%d",&t),qq.pb(mp(i,t));
102     S::work();
103     while(m--)
104     {
105         scanf("%s",tmp);
106         if(tmp[0]=='c')
107         {
108             scanf("%d%d",&L,&R);S::update(1,n,1);S::work();
109             printf("%d\n",S::gsum(L,R,1,n,1));
110         }
111         else
112         {
113             scanf("%d%d%d",&L,&R,&x);
114             S::delx(L,R,x,1,n,1);
115         }
116     }
117     return 0;
118 }

猜你喜欢

转载自www.cnblogs.com/hehe54321/p/9321479.html