gym102452 I Incoming Asteroids (2019-2020 ICPC Asia Hong Kong Regional Contest) 抽屜原理


題意

\(n\)個位置可以進行觀測。第一種操作可以在\(k\ (k\le3)\)個位置添加攝像頭,目標是收集\(y\)個單位的觀測值;第二種操作是在第\(x\)個位置所有的攝像頭產生了\(y\)個單位的觀測值,輸出該次操作使得操作一首次達到目標的數量和編號。強制在線。

思路

考慮\(k\)的值比較少,並由抽屜原理,我們可以對每個位置建立一個數據結構,插入操作一目標的\(\frac1k\),當這個位置的觀測值的增長超過插入值時,取出並更新操作一的目標並重新插入。這樣每次取出操作一的目標至少減少到原來的\(\frac{k-1}k\),對於每個操作一最多取出\(log_{\frac{k-1}k}(y)\)次,總復雜度\(O(m*log\ m*log\ y)\)

代碼

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,int> pli;
#define mp make_pair
const int maxn=2e5+5;
const int maxm=2e5+5;
ll v[maxn];
priority_queue<pli,vector<pli>,greater<pli> >st[maxn];

int Q[maxm][4];
int Y[maxm],D[maxm];
int vis[maxm];
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    
    int op,x,k,q,last=0,cnt=0;
    ll y;
    while(m--)
    {
        scanf("%d",&op);
        if(op==1)
        {
            scanf("%lld%d",&y,&k);
            y=y^last;

            ++cnt;
            Q[cnt][0]=k;
            Y[cnt]=D[cnt]=y;
            for(int kk=1;kk<=k;kk++)
            {
                scanf("%d",&q);
                q=q^last;
                Q[cnt][kk]=q;
                Y[cnt]+=v[q];
            }
            for(int kk=1;kk<=k;kk++)
                st[Q[cnt][kk]].push(mp(v[Q[cnt][kk]]+(D[cnt]+k-1)/k,cnt));

        }
        else //op==2
        {
            scanf("%d%d",&x,&y);
            x=x^last;
            y=y^last;

            vector<int>ans;
            v[x]+=y;
            while(!st[x].empty() && st[x].top().first<=v[x])
            {
                ll tmp=st[x].top().first;
                int i=st[x].top().second;
                st[x].pop();
                if(vis[i])continue;

                D[i]=Y[i];
                for(int kk=1;kk<=Q[i][0];kk++)
                    D[i]-=v[Q[i][kk]];

                if(D[i]<=0)
                {
                    ans.push_back(i);
                    vis[i]=1;
                }
                else
                {
                    k=Q[i][0];
                    for(int kk=1;kk<=k;kk++)
                        st[Q[i][kk]].push(mp(v[Q[i][kk]]+(D[i]+k-1)/k,i));
                }
            }
            sort(ans.begin(),ans.end());
            printf("%d",last=(int)ans.size());
            for(int i=0;i<ans.size();i++)
                printf(" %d",ans[i]);
            printf("\n");
        }
    }
    return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM