zoukankan      html  css  js  c++  java
  • gym102452 I Incoming Asteroids (2019-2020 ICPC Asia Hong Kong Regional Contest) 抽屉原理

    题意

    (n)个位置可以进行观测。第一种操作可以在(k (kle3))个位置添加摄像头,目标是收集(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("
    ");
            }
        }
        return 0;
    }
    
  • 相关阅读:
    转--- 一些概念不错的理解
    python 生产者 --- 消费者
    python GUI 之 tkinter
    读DataSnap源代码(二)
    读DataSnap源代码(一)
    FireDAC探索 (二)
    FireDAC内部初探
    C++Builder XE7 中“匿名”方法实现
    DelphiXE7 Datasnap TDSClientCallbackChannelManager内部实现初探
    C++ Builder使用VC DLL
  • 原文地址:https://www.cnblogs.com/intmian/p/13639732.html
Copyright © 2011-2022 走看看