• 2018.7.3模拟赛


    考炸了考炸了。。

    T1超级大水题,结果二分写挂???70分走人。。呜呜。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    
    using namespace std;
    const int MAXN = 100005;
    
    inline int rd(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0' || ch>'9') {if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0' && ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return x*f;
    }
    
    int n,ans=0;
    
    struct Time{
        int st,ed;
    }t[MAXN];
    
    inline bool cmp(Time a,Time b){
        return a.ed<b.ed;
    }
    
    inline bool check(int x){
        int k=x;
        for(register int i=1;i<=n;i++){
            k+=t[i].st;
            if(k>t[i].ed) return false;
        }
        return true;
    }
    
    int main(){
    //  freopen("manage.in","r",stdin);
    //  freopen("manage.out","w",stdout);
        n=rd();
        for(register int i=1;i<=n;i++)
            t[i].st=rd(),t[i].ed=rd();
        sort(t+1,t+1+n,cmp);
        int l=0,r=t[1].ed-t[1].st;
    //  for(register int i=1;i<=n;i++) cout<<t[i].st<<" "<<t[i].ed<<endl;
        if(r<0) {puts("-1");return 0;}
        while(l<=r){
            int mid=(l+r)>>1;
    //      cout<<l<<" "<<r<<" ";
    //      cout<<mid<<endl;
            if(check(mid)) {l=mid+1;ans=mid;}
            else r=mid-1;
        }
        if(ans==0 && !check(0)) puts("-1");
        else printf("%d",ans);
        return 0;
    }
    
    /*
    4
    3 5
    8 14
    5 20
    1 16
    */
    
    
    /*
    3
    1 100
    100 105
    110 300
    */

    T2 tarjan + 树上背包,结果tanjan边连成双向,60分滚蛋。我真的是菜的抠脚。

    
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    
    using namespace std;
    const int MAXN = 505;
    
    inline int rd(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0' || ch>'9') {if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0' && ch<='9') {x=(x<<1)+(x<<3)+ch-48;ch=getchar();}
        return x*f;
    }
    
    int n,m,w[MAXN],val[MAXN],W[MAXN],V[MAXN];
    int head[MAXN],cnt;
    int dfn[MAXN],low[MAXN],xx[MAXN],head_[MAXN],cnt_;
    int sta[MAXN],top,num;
    int col[MAXN],col_num,du[MAXN];
    int dp[MAXN][MAXN],ans;
    bool vis[MAXN];
            //dp[x][i] 表示以x为节点的子树,用了i的空间,最大权值 
    struct Edge{
        int nxt,to;
    }edge[MAXN<<1],edge_[MAXN<<1];
    
    inline void add(int bg,int ed){
        edge[++cnt].to=ed;
        edge[cnt].nxt=head[bg];
        head[bg]=cnt;
    }
    
    inline void add_(int bg,int ed){
        edge_[++cnt_].to=ed;
        edge_[cnt_].nxt=head_[bg];
        head_[bg]=cnt_;
    }
    
    inline void tarjan(int x){
        dfn[x]=low[x]=++num;
        vis[x]=1;
        sta[++top]=x;
        for(register int i=head[x];i;i=edge[i].nxt){
            int u=edge[i].to;
            if(!dfn[u]){
                tarjan(u);
                low[x]=min(low[x],low[u]);
            }
            else if(vis[u])
                low[x]=min(low[x],dfn[u]);
        }
        if(low[x]==dfn[x]){
            vis[x]=0;
            col_num++;
            while(sta[top]!=x){
                col[sta[top]]=col_num;
                vis[sta[top]]=0;
                top--;
            }
            top--;
            col[x]=col_num;
        }
    }
    
    inline void dfs(int x){
        for(register int i=W[x];i<=m;i++) dp[x][i]=V[x];
        for(register int i=head_[x];i;i=edge_[i].nxt){
            int u=edge_[i].to;
            dfs(u);
            for(register int j=m;j>=W[x];j--)
                for(register int k=0;k<=j-W[x];k++){
                    dp[x][j]=max(dp[x][j],dp[u][k]+dp[x][j-k]);
                }
        }   
    
    }
    
    int main(){
    //  freopen("software.in","r",stdin);
    //  freopen("software.out","w",stdout);
        n=rd();m=rd();
        for(register int i=1;i<=n;i++) w[i]=rd();
        for(register int i=1;i<=n;i++) val[i]=rd();
        for(register int i=1;i<=n;i++){
            xx[i]=rd();
            add(xx[i],i);
        }
        for(register int i=1;i<=n;i++) 
            if(!dfn[i]) tarjan(i);
    //  for(register int i=0;i<=n;i++) cout<<col[i]<<" ";cout<<endl;
        col[0]=0;
        for(register int i=1;i<=n;i++){
            W[col[i]]+=w[i];
            V[col[i]]+=val[i];
            if(col[i]==col[xx[i]]) continue;
            add_(col[xx[i]],col[i]);
            du[col[i]]++;
    //      if(col[xx[i]]==col[0]) mark[col[i]]=1;
        }
        for(register int i=1;i<=col_num;i++)
            if(!du[i]) add_(col[0],i);
    //  for(register int i=1;i<=col_num;i++) {
    //      if(i!=col[0])
    //      add(i,col[0]);
    //  }
    //  for(register int i=1;i<=col_num;i++) cout<<W[i]<<" "<<V[i]<<endl;
        dfs(0);
    //  for(register int i=0;i<=col_num;i++)
    //      for(register int j=0;j<=m;j++)
    //          cout<<i<<" "<<j<<" "<<dp[i][j]<<endl;
        ans=dp[0][m];
        printf("%d",ans);
        return 0;
    }
    
    /*
    3 10
    5 5 6 
    2 3 4 
    0 1 1
    */
    
    /*
    5 7
    4 2 1 2 3
    5 3 50 6 19
    0 1 2 2 1
    */
    
    /*
    7 14
    5 1 6 6 6 1 1
    1 2 1 2 1 5 4
    0 1 2 2 1 5 5
    */
    
    /*
    7 23
    4 4 4 4 1 4 4 
    100 100 100 100 1 5 4
    4 1 2 3 0 5 5
    */

    T3 不太会,打了个暴力+优化,极限卡过70。(传说中的n^2过100000?)
    正解是线段树,没往这上面像。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    
    using namespace std;
    const int MAXN = 400005;
    
    inline int rd(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-48;ch=getchar();}
        return x*f;
    }
    
    int n,m,cnt[MAXN];
    double mx[MAXN];
    
    inline int count(int l,int r,int x,double k){
        if(l==r) return mx[x]>k;
        int mid=(l+r)>>1;
        if(mx[x<<1]<=k) return count(mid+1,r,x<<1|1,k);
        else return cnt[x]-cnt[x<<1]+count(l,mid,x<<1,k);
        //注意cnt[x]-cnt[x<<1]不能直接写成cnt[x<<1|1],因为cnt数组表示的只是
        //每个区间的递增序列,与其他区间无关,所以左边可能挡住右边。
    }
    
    inline void change(int l,int r,int x,int q,double k){
        if(l==r){
            mx[x]=k;
            cnt[x]=1;
            return;
        }
        int mid=(l+r)>>1;
        if(q<=mid) change(l,mid,x<<1,q,k);
        else change(mid+1,r,x<<1|1,q,k);
        mx[x]=mx[x<<1]>mx[x<<1|1]?mx[x<<1]:mx[x<<1|1];
        cnt[x]=cnt[x<<1]+count(mid+1,r,x<<1|1,mx[x<<1]);
    }
    
    int main(){
        n=rd();m=rd();
        for(register int i=1;i<=m;i++){
            int x=rd(),y=rd();
            double k=(double)y/(double)x;
            change(1,n,1,x,k);
            printf("%d
    ",cnt[1]);
        }
    }
  • 相关阅读:
    POJ-3984-迷宫问题(bfs+记录路径)
    StringBuilder与String的区别
    845. 八数码(bfs+map)
    844. 走迷宫(bfs模板)
    843. n-皇后问题(dfs+输出各种情况)
    洛谷 P1337 [JSOI2004]平衡点 / 吊打XXX
    【模板】 线性筛质数
    接文游戏
    【NOIP2011提高组】计算系数
    洛谷 P3197 [HNOI2008]越狱
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/9676989.html
Copyright © 2020-2023  润新知