首页 > 代码库 > codeforcesRound378C-dfs+树状数组

codeforcesRound378C-dfs+树状数组

分成K个块,每个块内部dfs解决,然后用树状数组统计第i个元素前面有多少怪物已经消失,来计算当前的下标

技术分享
  1 #include<bits/stdc++.h>
  2 
  3 #define inf 0x3f3f3f3f
  4 
  5 const int maxn=1000;
  6 
  7 using namespace std;
  8 
  9 typedef pair<int,char> P;
 10 
 11 vector<P> G[maxn+10];
 12 
 13 int n;
 14 
 15 int k;
 16 
 17 int a[maxn+10];
 18 
 19 int b[maxn+10];
 20 
 21 int c[maxn+10];
 22 
 23 int d[maxn+10];
 24 
 25 int si[maxn+10];
 26 
 27 int lowbit(int x){
 28     return x&(-x);
 29 }
 30 
 31 void add(int x,int val){
 32        while(x<=n){
 33         d[x]+=val;
 34         x+=lowbit(x);
 35        }
 36 }
 37 
 38 int sum(int x){
 39    int res=0;
 40   while(x){
 41         res+=d[x];
 42         x-=lowbit(x);
 43   }
 44   return res;
 45 }
 46 
 47 int flag;
 48 
 49 int solve(int x,int y,int s){
 50     // printf("%d\n",s);
 51      if(s==b[x]){
 52         return 1;
 53      }
 54      //printf("%d %d\n",y,s);
 55      for(int i=y+1;i<=c[x];i++){
 56         if(a[i]==inf) continue;
 57         if(a[i]!=a[y]){
 58                 //printf("%d %d\n",i,y);
 59                 if(a[y]>a[i]){
 60                // printf("%d %d\n",y,i);
 61                 int temp=a[i];
 62                 int temp1=a[y];
 63                 a[i]+=a[y];
 64                 a[y]=inf;
 65                 add(y,1);
 66                 //printf("%d %d %d\n",y,y-sum(y)+1,sum(y));
 67                 G[x].push_back(P(y-sum(y)+1,R));
 68                 //printf("%d %d %d %d\n",x,i,y,s+temp);
 69                 if(solve(x,i,s+temp)){
 70                        // printf("dsasd\n");
 71                         return 1;
 72                 }  else {
 73                   a[i]=temp;
 74                   a[y]=temp1;
 75                   add(y,-1);
 76                   G[x].erase(G[x].end()-1);
 77                   return 0;
 78                 }
 79                 }
 80                 else {
 81              //   printf("%d %d\n",i,y);
 82                 int temp=a[i];
 83                 int temp1=a[y];
 84                 a[y]+=a[i];
 85                 a[i]=inf;
 86                 add(i,1);
 87                  G[x].push_back(P(i-sum(i)+1,L));
 88                // printf("%d %d\n",y,s+temp);
 89                  if(solve(x,y,s+temp)){
 90                         return 1;
 91                 }  else {
 92                   a[i]=temp;
 93                   a[y]=temp1;
 94                   add(i,-1);
 95                   G[x].erase(G[x].end()-1);
 96                   return 0;
 97                 }
 98                 }
 99 
100         } else break;
101      }
102      for(int i=y-1;i>c[x-1];i--){
103          if(a[i]==inf) continue;
104         // printf("%d %d\n",i,y);
105          if(a[i]!=a[y]){
106                 if(a[y]>a[i]){
107                 int temp=a[i];
108                 int temp1=a[y];
109                 a[i]+=a[y];
110                 a[y]=inf;
111                 add(y,1);
112                 G[x].push_back(P(y-sum(y)+1,L));
113                 if(solve(x,i,s+temp)){
114                         return 1;
115                 }  else {
116                   a[i]=temp;
117                   a[y]=temp1;
118                   add(y,-1);
119                   G[x].erase(G[x].end()-1);
120                   return 0;
121                 }
122                 }
123                 else {
124                 int temp=a[i];
125                 int temp1=a[y];
126                 a[y]+=a[i];
127                 a[i]=inf;
128                 add(i,1);
129                  G[x].push_back(P(i-sum(i)+1,R));
130                  if(solve(x,y,s+temp)){
131                         return 1;
132                 }  else {
133                  a[i]=temp;
134                  a[y]=temp1;
135                  add(i,-1);
136                  G[x].erase(G[x].end()-1);
137                   return 0;
138                 }
139                 }
140 
141         } else break;
142      }
143      for(int i=c[x-1]+1;i<=c[x];i++){
144         if(a[i]!=inf&&i!=y&&a[i]!=a[y]){
145           //printf("%d %d\n",i,s);
146           if(solve(x,i,a[i])) return 1;
147         }
148       }
149      return 0;
150 }
151 
152 int main()
153 {
154     scanf("%d",&n);
155     for(int i=1;i<=n;i++){
156         scanf("%d",&a[i]);
157     }
158     scanf("%d",&k);
159     for(int i=1;i<=k;i++){
160         scanf("%d",&b[i]);
161     }
162     int cnt=1;
163     int temp=0;
164     for(int i=1;i<=n;i++){
165         if(temp<b[cnt]){
166                 temp+=a[i];
167                 si[cnt]++;
168         }
169         if(temp==b[cnt]){
170                 c[cnt]=i;
171                 cnt++;
172                 temp=0;
173         } else if(temp>b[cnt]) {
174                flag=1;
175                break;
176         }
177     }
178     if(flag||cnt!=k+1){
179         printf("NO\n");
180     } else {
181        for(int i=1;i<=k;i++){
182                 if(si[i]==1) continue;
183                 int f=0;
184            for(int j=c[i-1]+1;j<c[i];j++){
185                 if(a[j]!=a[j+1]){
186                         if(solve(i,j,a[j])){
187                                 f=1;
188                                 break;
189                         } else {
190                          f=0;
191                          break;
192                         }
193                 }
194            }
195            if(!f){
196                 if(solve(i,c[i],a[c[i]])){
197                         f=1;
198                 }
199            }
200            if(!f){
201                 printf("NO\n");
202                 return 0;
203            }
204        }
205        printf("YES\n");
206        for(int i=1;i<=k;i++){
207          for(int j=0;j<G[i].size();j++){
208                 printf("%d %c\n",G[i][j].first,G[i][j].second);
209          }
210        }
211     }
212     return 0;
213 }
View Code

 

codeforcesRound378C-dfs+树状数组