Codeforces Round #766 (Div. 2)思路整理

灵感当然可以用来做题,但迟早会有灵感枯竭的一天。
Codeforces Round #766 (Div. 2)
A. Not Shading
答案只可能为0,-1,1,2,分情况讨论即可。
B. Not Sitting
可以发现一个比较显然的性质,最后Tina的座位一定是四个角是最优的。那么考虑Rahul的话,就是每个点的代价就是当前这个点到四个角的距离取max.这样再把所有的点从小到大排序,就是Rahul依次会坐的点。
C. Not Assigning
这个构造就比较有意思(我一直都觉得cf的构造题真的很有意思。)
可以发现由于每个数都是质数,考虑一个有三个出度的点,那么这三个边至少有两个是奇数,(另外一个质数可以是2)。那么这两个奇数相加就是偶数,不符合题意。所以每个点的出边最多是2.考虑这样的树只能是一条链,所以直接特判链的情况,然后可以按照2,3,2,3...这样赋值即可。
D. Not Adding
这个题当初真的是卡了很久....可以发现n和ai的范围都是1e6的级别,正常思路都是先考虑用n的数量级来做,考虑两两之间的操作呀什么的。可怎么样都想不到后,可以从值域的角度思考,发现ai的数据也为1e6,那么我们可以枚举每一个数来判断这个数能不能被添加,这个数能被添加的条件是这个数能是两个数(或多个数)的gcd,换言之,这个数的几个倍数,之间除掉这个数后,剩下的数互质。那么这样我们就可以做了,枚举一下每一个数,之后枚举这个数的倍数,考虑这些倍数之间除掉这个数后是否互质即可。
E. Not Escaping
spfa已经死了,比赛的时候打了spfa,然后由于一点小失误没调出来,之后再交,果然T了,果然不能相信spfa.....
发现这个图建出来后层与层之间是单向的边,完全可以用DP,然后单独考虑某一层时,由于是左右线性的,我完全可以从左到右然后从右到左,做两次DP即可。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+10;
int n,m,k,T,num,w[N],b[N];
ll f[N*2];
map<pair<int,int>,int>id;
map<int,bool>fs[N];
vector<int>v[N];
vector<pair<int,int> >vs[N*2];
inline void clear()
{
    id.clear();
    for(int i=1;i<=n;++i) fs[i].clear(),v[i].clear();
    for(int i=1;i<=num;++i) vs[i].clear();
    num=0;
}
int main()
{
//    freopen("1.in","r",stdin); 
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&n,&m,&k);
        clear();
        for(int i=1;i<=n;++i) scanf("%d",&w[i]);
        id[{1,1}]=++num;id[{n,m}]=++num;
        fs[1][1]=1;fs[n][m]=1;
        v[1].push_back(1);
        v[n].push_back(m);
        for(int i=1;i<=k;++i)
        {
            int a,b,c,d,h;
            scanf("%d%d%d%d%d",&a,&b,&c,&d,&h);
            if(id.find({a,b})==id.end()) id[{a,b}]=++num;
            if(id.find({c,d})==id.end()) id[{c,d}]=++num; 
            vs[id[{a,b}]].push_back({id[{c,d}],h});
            if(fs[a].find(b)==fs[a].end())
            {
                v[a].push_back(b);
                fs[a][b]=1;
            }
            if(fs[c].find(d)==fs[c].end())
            {
                v[c].push_back(d);
                fs[c][d]=1;
            }
        }
        for(int i=1;i<=num;++i) f[i]=0xefefefefefefefef;
        f[1]=0;
        for(int i=1;i<=n;++i)
        {
            sort(v[i].begin(),v[i].end());
            int tot=0;
            for(int j=0;j<v[i].size();++j) b[++tot]=id[{i,v[i][j]}];
            for(int j=1;j<tot;++j) 
                f[b[j+1]]=max(f[b[j+1]],f[b[j]]-(ll)w[i]*abs(v[i][j]-v[i][j-1]));
            for(int j=tot;j>1;--j)
                f[b[j-1]]=max(f[b[j-1]],f[b[j]]-(ll)w[i]*abs(v[i][j-1]-v[i][j-2]));
            for(int j=1;j<=tot;++j)
                for(auto y:vs[b[j]])
                       f[y.first]=max(f[y.first],f[b[j]]+y.second);           
        }
        if(f[2]<-1e18) puts("NO ESCAPE");
        else printf("%lld\n",-f[2]);
    }
    return 0;
} 
posted @ 2022-01-19 10:15  逆天峰  阅读(103)  评论(0编辑  收藏  举报
作者:逆天峰
出处:https://www.cnblogs.com/gcfer//