Submission #1099024

#TimeUsernameProblemLanguageResultExecution timeMemory
1099024alexander_707070Teams (IOI15_teams)C++14
0 / 100
321 ms265812 KiB
#include<bits/stdc++.h>
#include "teams.h"

#define MAXN 1000007
using namespace std;

int n,m,a[MAXN],b[MAXN];
pair<int,int> p[MAXN];
int k[MAXN];

struct interval{
    int l,r,k,e;

    int len(){
        return r-l+1;
    }
};

interval combine(interval a,interval b){
    interval c={a.l,b.r,0,0};

    if(a.k>a.len())swap(a,b);

    if(a.k>a.len() and b.k>b.len()){
        c.k=c.len()+1;
        c.e=0;
    }else if(b.k>b.len()){
        c.k=a.k+b.len();
        c.e=a.e;
    }else{
        if(a.e>b.e)swap(a,b);

        c.e=a.e;
        c.k=a.k+b.k-1;
    }

    return c;
}

struct query{
    int l,r;
 
    inline friend bool operator < (query fr,query sc){
        return fr.r>sc.r;
    }
}s[MAXN];
 
bool cmp(query fr,query sc){
    return fr.l<sc.l;
}

priority_queue<query> q;

struct PST{
    struct node{
        int l,r,sum;
    };

    node tree[MAXN*30];
    int root[MAXN],num,last;

    void upgrade(){
        last++; root[last]=num;
    }

    void addnode(int l,int r){
        num++;
        tree[num].l=l; tree[num].r=r;
    }

    int update(int v,int l,int r,int pos){
        if(l==r){
            addnode(0,0);
            tree[num].sum=tree[v].sum+1;
            return num;
        }else{
            int tt=(l+r)/2;
            int lt=tree[v].l,rt=tree[v].r;

            if(pos<=tt){
                lt=update(tree[v].l,l,tt,pos);
            }else{
                rt=update(tree[v].r,tt+1,r,pos);
            }

            addnode(lt,rt);
            tree[num].sum=tree[lt].sum+tree[rt].sum;
            return num;
        }
    }

    int getkth(int v1,int v2,int l,int r,int k){
        if(l==r)return l;

        int tt=(l+r)/2;
        if(tree[tree[v2].l].sum-tree[tree[v1].l].sum>=k)return getkth(tree[v1].l,tree[v2].l,l,tt,k);
        return getkth(tree[v1].r,tree[v2].r,tt+1,r,k-(tree[tree[v2].l].sum-tree[tree[v1].l].sum));
    }

    void upd(int x){
        update(root[last],1,n,x);
        upgrade();
    }

    int kth(int l,int r,int k){
        return getkth(root[l-1],root[r],1,n,k);
    }

    int smallest(int l,int r,int val){
        int from=0,to=r-l+2,tt;

        while(from+1<to){
            tt=(from+to)/2;
            if(kth(l,r,tt)>=val){
                to=tt;
            }else{
                from=tt;
            }
        }

        return to;
    }
}seg;


void init(int N, int A[], int B[]) {
//void init(int N, vector<int> A, vector<int> B) {
    n=N;
    for(int i=1;i<=n;i++){
        a[i]=A[i-1]; b[i]=B[i-1];
        p[i]={A[i-1],B[i-1]};
    }
    sort(p+1,p+n+1);

    for(int i=1;i<=n;i++)seg.upd(p[i].second);
}

int findpos(int from,int val){
    int l=from,r=n+1,tt;
    while(l+1<r){
        tt=(l+r)/2;
        if(p[tt].first<=val){
            l=tt;
        }else{
            r=tt;
        }
    }

    return l;
}

int smart(){
    sort(k+1,k+m+1);

    vector<interval> w;

    int pt=0;
    for(int i=1;i<=m;i++){
        int nxt=findpos(pt,k[i]);

        if(nxt>pt){
            w.push_back({pt+1,nxt,1,seg.kth(pt+1,nxt,1)});
            pt=nxt;
        }

        for(int f=int(w.size())-1;f>=0;f--){
            int s=seg.smallest(w[f].l,w[f].r,k[i]);
            if(s<w[f].k)break;

            w[f].k=s;
            if(s<=w[f].len())w[f].e=seg.kth(w[f].l,w[f].r,s);
            else w[f].e=0;
        }

        if(w.empty())return 0;

        while(k[i]>0){

            if(w.size()==1){
                if(w[0].k+k[i]-1>w[0].len())return 0;
                w[0].k+=k[i];
                break;
            }

            interval s=w.back();
            for(int z=20;z>=0;z--){
                if((1<<z)>s.len()-s.k+1 or (1<<z)>k[i])continue;

                int curr=seg.kth(s.l,s.r,s.k+(1<<z)-1);
                if(curr<w[w.size()-2].e){
                    k[i]-=(1<<z);
                    s.k+=(1<<z);
                }
            }
            
            if(s.k<=s.len())s.e=seg.kth(s.l,s.r,s.k);
            else s.e=0;

            w[w.size()-1]=s;

            if(k[i]>0){
                w[w.size()-2]=combine(w[w.size()-2],w[w.size()-1]);
                w.pop_back();
            }
        }
    }
}

int dumb(){
    sort(k+1,k+m+1);
 
    for(int i=1;i<=n;i++){
 
        int l=0,r=m+1,tt;
        while(l+1<r){
            tt=(l+r)/2;
            if(k[tt]<=b[i]){
                l=tt;
            }else{
                r=tt;
            }
        }
 
        s[i].r=l;
 
        l=0; r=m+1;
        while(l+1<r){
            tt=(l+r)/2;
            if(k[tt]>=a[i]){
                r=tt;
            }else{
                l=tt;
            }
        }
 
        s[i].l=r;
    }
 
    sort(s+1,s+n+1,cmp);
    while(!q.empty())q.pop();
 
    int pt=1;
    for(int i=1;i<=m;i++){
        while(pt<=n and s[pt].l<=i){
            q.push(s[pt]); pt++;
        }
        
        while(!q.empty() and q.top().r<i)q.pop();
 
        for(int f=0;f<k[i];f++){
            if(q.empty())return 0;
            q.pop();
        }
    }
 
	return 1;
}

int can(int M,int K[]) {
//int can(int M,vector<int> K) {
    m=M;
    for(int i=1;i<=m;i++){
        k[i]=K[i-1];
    }

    if(m>=n/10){
        return dumb();
    }else{
        return smart();
    }

	return 1;
}

/*int main(){

    init(4,{1,2,2,2},{2,3,3,4});
    cout<<can(2,{1,3})<<"\n";
    cout<<can(2,{1,1})<<"\n";

	return 0;
}*/

Compilation message (stderr)

teams.cpp: In function 'interval combine(interval, interval)':
teams.cpp:19:38: warning: declaration of 'b' shadows a global declaration [-Wshadow]
   19 | interval combine(interval a,interval b){
      |                             ~~~~~~~~~^
teams.cpp:7:17: note: shadowed declaration is here
    7 | int n,m,a[MAXN],b[MAXN];
      |                 ^
teams.cpp:19:27: warning: declaration of 'a' shadows a global declaration [-Wshadow]
   19 | interval combine(interval a,interval b){
      |                  ~~~~~~~~~^
teams.cpp:7:9: note: shadowed declaration is here
    7 | int n,m,a[MAXN],b[MAXN];
      |         ^
teams.cpp: In member function 'int PST::getkth(int, int, int, int, int)':
teams.cpp:92:46: warning: declaration of 'k' shadows a global declaration [-Wshadow]
   92 |     int getkth(int v1,int v2,int l,int r,int k){
      |                                          ~~~~^
teams.cpp:9:5: note: shadowed declaration is here
    9 | int k[MAXN];
      |     ^
teams.cpp: In member function 'int PST::kth(int, int, int)':
teams.cpp:105:29: warning: declaration of 'k' shadows a global declaration [-Wshadow]
  105 |     int kth(int l,int r,int k){
      |                         ~~~~^
teams.cpp:9:5: note: shadowed declaration is here
    9 | int k[MAXN];
      |     ^
teams.cpp: In function 'int smart()':
teams.cpp:167:17: warning: declaration of 's' shadows a global declaration [-Wshadow]
  167 |             int s=seg.smallest(w[f].l,w[f].r,k[i]);
      |                 ^
teams.cpp:46:2: note: shadowed declaration is here
   46 | }s[MAXN];
      |  ^
teams.cpp:185:22: warning: declaration of 's' shadows a global declaration [-Wshadow]
  185 |             interval s=w.back();
      |                      ^
teams.cpp:46:2: note: shadowed declaration is here
   46 | }s[MAXN];
      |  ^
teams.cpp:155:22: warning: control reaches end of non-void function [-Wreturn-type]
  155 |     vector<interval> w;
      |                      ^
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...