Codeforces1257D (greedy + buffer, or binary tree line +)

Title effect: n-monster, each monster has an ability value a. There are m warriors, each warrior has a strength and endurance S. P Tomorrow can choose a warrior to fight the monster, you must fight the order, if this ability Warriors P> = a then you can beat this monster, we must lay a monster, but only up to a day to play S a monster. If the force P <a. The Warriors came back. End of the day, every warrior can be used many times. Q. How many days requires a minimum, be able to defeat all the monsters all.

 

A range of data are n (1 <= n <= 2e5), m (1 <= m <= 2e5) (1 <= pi <= 1e9,1 <= si <= n) of all inquiries n + m add up to no more than 2e5

 

This question is a normal way of thinking (or My general idea is) First, we ask how to solve the minimum time ago i just monsters? ? ? ? ?   

Then it can be considered to solve the problem of the i-th monster warrior he addressed intervals, such operations can solve half, then in the maintenance of a segment tree? ? ? ? ?

But this feeling a little difficult to write? And it is easy wa, wa I do not know how many times.

Here is the code written in the game:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <cmath>
  6 #include <bitset>
  7 #include <set>
  8 typedef long long ll;
  9 using namespace std;
 10 const int maxn=201000;
 11 int t,n,m;
 12 int num[maxn],sum1[maxn<<2],sum2[maxn<<2],dp[maxn],q[maxn],p[maxn],s[maxn];
 13 struct node{
 14     int pi,si;
 15 };
 16 node fnum[maxn];
 17  
 18 bool cmp(node n1,node n2){
 19     if(n1.pi==n2.pi) return n1.si<n2.si;
 20     else return  n1.pi<n2.pi;
 21 }
 22  
 23 void build1(int l,int r,int rt){
 24     if(l==r){
 25         sum1[rt]=num[l];
 26         return;
 27     }
 28     int mid=(l+r)/2;
 29     build1(l,mid,rt<<1);
 30     build1(mid+1,r,rt<<1|1);
 31     sum1[rt]=max(sum1[rt<<1],sum1[rt<<1|1]);
 32 }
 33  
 34 int ask(int l,int r,int rt,int L,int R){
 35     if(L<=l&&r<=R) return sum1[rt];
 36     int mid=(l+r)/2;
 37     int ans=0;
 38     if(L<=mid) ans=max(ans,ask(l,mid,rt<<1,L,R));
 39     if(R>mid) ans=max(ans,ask(mid+1,r,rt<<1|1,L,R));
 40     return ans;
 41 }
 42  
 43 void adds(int l,int r,int rt,int k,int k1){
 44     if(l==r){
 45         sum2[rt]=k1;
 46         return;
 47     }
 48     int mid=(l+r)/2;
 49     if(k<=mid) adds(l,mid,rt<<1,k,k1);
 50     else  adds(mid+1,r,rt<<1|1,k,k1);
 51     sum2[rt]=min(sum2[rt<<1|1],sum2[rt<<1]);
 52 }
 53  
 54 int Min(int l,int r,int rt,int L,int R){
 55     if(L<=l&&r<=R) return sum2[rt];
 56     int mid=(l+r)/2;
 57     int ans=(int)(1e9+7);
 58     if(L<=mid) ans=min(ans,Min(l,mid,rt<<1,L,R));
 59     if(R>mid) ans=min(ans,Min(mid+1,r,rt<<1|1,L,R));
 60     return ans;
 61 }
 62  
 63  
 64 bool check(int l,int  r){
 65     int q1=ask(1,n,1,l,r);
 66     int iscan=(int)(lower_bound(p+1,p+m+1,q1)-p);
 67     //if(l==1&&r==2) printf("%d  %d  %d %d\n",q1,num[1],num[2],iscan);
 68     if(iscan>=1&&iscan<=m&&q[iscan]>=(r-l+1)) return true;
 69     return false;
 70 }
 71  
 72 int main(){
 73     scanf("%d",&t);
 74     while(t--){
 75         scanf("%d",&n);
 76         for(int i=1;i<=n;i++) scanf("%d",&num[i]);
 77         build1(1,n,1);
 78         scanf("%d",&m);
 79         for(int i=1;i<=m;i++) scanf("%d%d",&fnum[i].pi,&fnum[i].si);
 80         sort(fnum+1,fnum+m+1,cmp);
 81         int flag=0;
 82         for(int i=1;i<=m;i++){
 83             //if(fnum[i].pi<num[i])  flag=1;
 84             p[i]=fnum[i].pi;s[i]=fnum[i].si;
 85         }
 86         for(int i=1;i<=n;i++) if(fnum[m].pi<num[i]) flag=1;
 87         if(flag==1){printf("-1\n");continue;}
 88  
 89         q[m]=fnum[m].si;
 90         for(int i=m-1;i>=1;i--)  q[i]=max(q[i+1],s[i]);
 91  
 92         dp[1]=1;dp[0]=0;
 93         adds(0,n,1,1,1);   adds(0,n,1,0,0);
 94         for(int i=2;i<=n;i++){
 95             int l=1,r=i,ans=i;
 96             while(l<=r){
 97                 int mid=(l+r)/2;
 98                 if(check(mid,i)==1){ans=mid;r=mid-1;}
 99                 else l=mid+1;
100             }
101             // cout<<ans-1<<"  "<<i-1<<endl;
102             dp[i]=Min(0,n,1,ans-1,i-1)+1;
103             adds(0,n,1,i,dp[i]);
104         }
105         printf("%d\n",dp[n]);
106     }
107     return 0;
108 }
View Code

 

 

Then that is a very wonderful solution, I do not know how to think of such a solution in which the exam? ? ? ? ? ?

tql !!!

(1): First, we can find that this thing can be greedy, that is, for every warrior he can kill monsters as possible, all in all is what can be more than just a monster on the number of what the monster, greedy to go directly to ok

 

(2): Then we need to discard m this stuff, because futile, considering the maximum fi can i days of continuous fighting warrior, so if we can stick i days, go on line and directly, without the need to consider that particular warrior

 

(3): i directly mapped to the range above, this is best done

 

Here is the code:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <cmath>
 6 #include <bitset>
 7 typedef long long ll;
 8 using namespace std;
 9 const int maxn=201000;
10 int num[maxn],mx[maxn];
11 int t,n,m;
12 int main(){
13     scanf("%d",&t);
14     while(t--){
15         scanf("%d",&n);
16         for(int i=1;i<=n;i++) scanf("%d",&num[i]);
17         for(int i=1;i<=n;i++) mx[i]=0;
18         scanf("%d",&m);
19         for(int i=1;i<=m;i++){
20             int pi,si;
21             scanf("%d%d",&pi,&si);
22             mx[si]=max(mx[si],pi);
23         }
24         for(int i=n-1;i>=1;i--)  mx[i]=max(mx[i],mx[i+1]);
25 
26         int pos=1,flag=1,day=0;
27         while(pos<=n){
28             day++; int tmp=pos,maxn=0;
29             while(tmp<=n){
30                 maxn=max(maxn,num[tmp]);
31                 if(maxn>mx[tmp-pos+1]) break;
32                 ++tmp;
33             }
34             if(tmp==pos){
35                 flag=0;break;
36             }
37             pos=tmp;
38         }
39         if(!flag) day=-1;
40         printf("%d\n",day);
41     }
42     return 0;
43 }
View Code

Guess you like

Origin www.cnblogs.com/pandaking/p/12035028.html