• cf round546 cde


    第一题会卡一下同时用set和cin。。

    其他的注意下矩阵对角线下标的应用即可

    #include<bits/stdc++.h>
    using namespace std;
    #define maxn 2005
    int mp1[maxn][maxn],n,m,mp2[maxn][maxn];
    vector<int>s1[maxn],s2[maxn];
    int main(){
        cin>>n>>m;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                scanf("%d",&mp1[i][j]),s1[i+j].push_back(mp1[i][j]);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                scanf("%d",&mp2[i][j]),s2[i+j].push_back(mp2[i][j]);
        
        for(int i=2;i<=n+m;i++){
            sort(s1[i].begin(),s1[i].end());
            sort(s2[i].begin(),s2[i].end());
            if(s1[i]!=s2[i]){
                puts("NO");
                return 0;
            }
        }
        puts("YES");
    } 
    /*
    问题可转化为有多少个点可以把最后一个点(n)推移上来
    按位置将所有点排序,建立一个集合s
    起初将最后一个点放在集合里,然后倒序访问之前的结点,
    如果结点i可以将n推上来,那么之后的结点j再要将n推上来时就不用考虑i,
    否则需要考虑j是否可以推到i后面,再然后将n推上来 
        如果之前结点i有边到达集合里的所有点,那么这个结点就可以把点n推上来,
        如果不行,这个点i放入集合中
    复杂度分析:每条边都会在集合里判断一次,mlogn 
    */
    #include<bits/stdc++.h>
    #include<set>
    using namespace std;
    #define maxn 500005
    int m,n,pos[maxn],id[maxn];
    set<int>s,G[maxn];
    set<int>::iterator it;
     
    int main(){
        cin>>n>>m;
        for(int i=1;i<=n;i++)
            scanf("%d",&id[i]),pos[id[i]]=i;
        int u,v;
        for(int i=1;i<=m;i++){
            scanf("%d%d",&u,&v);
            G[u].insert(v);
        }
        
        int ans=0;
        s.insert(id[n]);
        for(int i=n-1;i>=1;i--){
            int cur=id[i],flag=0;
            for(it=s.begin();it!=s.end();it++)
                if(G[cur].find(*it)==G[cur].end()){
                    flag=1;
                    s.insert(cur);
                    break;
                }
            if(!flag)ans++;
        }
        cout<<ans<<endl;
    }

    e也太难了。。留个坑吧

    补坑。。区间覆盖线段树调了半天,最后发现有个地方没写long long ...气死我了.

    所以总结一下,,区间覆盖和区间更新的pushdown还是有点差距的,,还有本题的lazy初始值要设为INF

    /*
    给定数组a1...an, k1...kn-1
    两种操作:
    第一种为ai+x,完成本次操作后若ai+1<ai+ki,则ai+1=ai+ki,以此类推
        即后面的数不得小于前面的数+ki
    第二种为求和操作 
    推导公式可得a1<=a2-sumk1<=a3-sumk2<=a4-sumk3...<=an-sumkn-1
    令 bi=ai-sumki-1
    b1<=b2<=b3<=b4...<=bn
    ai+x <=> bi+x,同时所有在bi后面且小于bi+x的数都要变成bi+x
        所以直接用lower_bound找到第一个不小于bi+x的数 
    用线段树维护bi,进行区间覆盖操作
    query时先query 区间bi的和,再使用前缀和求出区间sumki的值
    注意lazy 
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define maxn 200005
    #define ll long long
    ll n,m,a[maxn],k[maxn],b[maxn],sumk[maxn],sumkk[maxn];
    #define INF 1e18 
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    ll sum[maxn<<2],lazy[maxn<<2];
    inline void pushup(int rt){
        sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    }
    inline void pushdown(int l,int r,int rt){
        if(lazy[rt]!=INF+1){
            int m=l+r>>1;
            sum[rt<<1]=lazy[rt]*(m-l+1);
            sum[rt<<1|1]=lazy[rt]*(r-m);
            lazy[rt<<1]=lazy[rt];
            lazy[rt<<1|1]=lazy[rt];
            lazy[rt]=INF+1;
        }
    }
    void build(int l,int r,int rt){
        lazy[rt]=INF+1;
        if(l==r){sum[rt]=b[l];return;}
        int m=l+r>>1;
        build(lson);build(rson);
        pushup(rt);
    }
    void modify(int L,int R,ll val,int l,int r,int rt){
        if(L<=l&&R>=r){
            lazy[rt]=val;sum[rt]=val*(r-l+1);
            return;
        }
        pushdown(l,r,rt);
        int m=l+r>>1;
        if(L<=m)modify(L,R,val,lson);
        if(R>m)modify(L,R,val,rson);
        pushup(rt);
    }
    
    ll query(int L,int R,int l,int r,int rt){
        if(L<=l && R>=r)return sum[rt];
        pushdown(l,r,rt);
        int m=l+r>>1;
        ll res=0;
        if(L<=m)res+=query(L,R,lson);
        if(R>m)res+=query(L,R,rson);
        return res;
    } 
    void add(int i,ll val){
        if(val==0)return;
        ll cur=query(i,i,1,n,1)+val;//查询第l个点当前值 
        int l=i,r=n,mid,ans=l;//查询最右边的比cur小的数 
        while(l<=r){
            mid=l+r>>1;
            if(query(mid,mid,1,n,1)<cur)
                ans=mid,l=mid+1;
            else r=mid-1;
        }
        modify(i,ans,cur,1,n,1);
    }
    int main(){
        cin>>n;
        for(int i=1;i<=n;i++)cin>>a[i];
        for(int i=1;i<n;i++)cin>>k[i];
        for(int i=2;i<=n;i++)sumk[i]=sumk[i-1]+k[i-1];
        for(int i=1;i<=n;i++)b[i]=a[i]-sumk[i];
        for(int i=2;i<=n;i++)sumkk[i]=sumkk[i-1]+sumk[i];
        build(1,n,1);
        cin>>m;
        while(m--){
            char op[2];ll l,r;
            cin>>op>>l>>r;
            if(op[0]=='+')add(l,r);
            else cout<<query(l,r,1,n,1)+sumkk[r]-sumkk[l-1]<<"
    ";
        }
        return 0;
    }
  • 相关阅读:
    Eclipse配置SVN的几种方法及使用详情
    重新定位svn地址的方法(windows和linux),svn switch(sw)的帮助信息
    SVN版本库修改URL路径或者IP地址
    DEA中MAVEN项目有多个子目录,如何加载构建
    DBA的40条军规
    搜索 比MySQL快10倍?这可能是目前AWS Aurora最详解读!
    HttpClient 4.5.3 get和post请求
    基于HttpClient4.5.2实现的HttpClient工具类
    httpClient使用总结
    为何只能在其关联的线程内启动timer?(Qt会检查一致性,否则就不执行)
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10519971.html
Copyright © 2020-2023  润新知