2019CCPC秦皇岛赛区

目录

  • Solutions

    • F. Forest Program
    • I. Invoker
    • J. MUV LUV EXTRA

Link

Solutions


F. Forest Program

题意:

思路:
dfs+栈 判环
设图中环的大小分别为 \(c_1\) \(c_2\), ..., \(c_k\),不属于任何一个环的边数为 \(b\),则答案为:
\(2^b*\prod _{i=1}^{k}{(2^{c_i}-1)}\)
dfs 判环时 各点入栈 若点已存在于栈中 则存在环 计算环大小即可 不必出栈
跑一遍连通图即可计算出所有环
代码:

[]

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=3e6+5;
const int mod=998244353;
vector<int>edge[maxn];
int vis[maxn],ins[maxn],s[maxn];
int top;
int n,m;
ll ans;
void init()
{
    ans=1;
    memset(vis,0,sizeof vis);
    memset(ins,0,sizeof ins);
    for(int i=1;i<=n;i++) edge[i].clear();
    top=0;
}
ll qPow(ll n,int a)
{
    ll res=1;
    while(a)
    {
        if(a&1) res=res*n%mod;
        n=n*n%mod;
        a>>=1;
    }
    return res;
}
void dfs(int u,int pre)
{
    s[++top]=u;
    ins[u]=1;
    vis[u]=1;
    for(auto x:edge[u])
    {
        if(!vis[x]) dfs(x,u);
        else if(ins[x]&&x!=pre)
        {
            int t=top;
            int sum=1;
            while(s[t]!=x)
            {
                t--;
                sum++;
            }
            m-=sum;
            ans=ans*(qPow(2,sum)-1+mod)%mod;
        }
    }
    ins[s[top]]=0;
    top--;
}
int main()
{
    int a,b;
    while(~scanf("%d%d",&n,&m))
    {
        init();
        for(int i=0;i<m;i++)
        {
            scanf("%d%d",&a,&b);
            edge[a].push_back(b);
            edge[b].push_back(a);
        }
        for(int i=1;i<=n;i++)
            if(!vis[i])
                dfs(i,i);
        printf("%lld\n",ans*qPow(2,m)%mod);
    }
    return 0;
}

I. Invoker

题意:

思路:
dp
一个 special skill 最多有 \(6\) 种排列
将前后两个技能进行 \(36\) 种排列配对
\(dp[i][j]\)( \(i\) 为第 \(i\) 个技能, \(j\) 为技能 \(i\) 的第 \(j\) 种排列)
\(dp[i][j]=min(dp[i][j],dp[i-1][k]+cmp(s[i-1]_{k},s[i]_j)(0\le j,k\le 5))\)
代码:

[]

#include<bits/stdc++.h>
using namespace std;
char s[100001];
map<char,int>mp;
char p[10][6][4]={
                    "QWE","QEW","WQE","WEQ","EQW","EWQ",
                    "WWW","WWW","WWW","WWW","WWW","WWW",
                    "WEE","WEE","EWE","EEW","EWE","EEW",
                    "QEE","QEE","EQE","EEQ","EQE","EEQ",
                    "QQE","QEQ","QQE","QEQ","EQQ","EQQ",
                    "EEE","EEE","EEE","EEE","EEE","EEE",
                    "QQW","QWQ","QQW","QWQ","WQQ","WQQ",
                    "QWW","QWW","WQW","WWQ","WQW","WWQ",
                    "QQQ","QQQ","QQQ","QQQ","QQQ","QQQ",
                    "WWE","WEW","WWE","WEW","EWW","EWW",
                  };
int dp[100001][6];
int cmp(int a,int b,int c,int d)
{
    if(!strcmp(p[a][b],p[c][d])) return 0;
    else if(p[a][b][1]==p[c][d][0]&&p[a][b][2]==p[c][d][1]) return 1;
    else if(p[a][b][2]==p[c][d][0]) return 2;
    return 3;
}
int main()
{
    mp['B']=0,mp['C']=1,mp['D']=2,mp['F']=3,mp['G']=4,mp['T']=5,mp['V']=6,mp['X']=7,mp['Y']=8,mp['Z']=9;
    while(~scanf("%s",s))
    {
        for(int i=0;s[i];i++)
            for(int j=0;j<6;j++)
                dp[i][j]=(i+1)*3+i+1;
        for(int i=0;i<6;i++) dp[0][i]=3;
        for(int i=1;s[i];i++)
            for(int j=0;j<6;j++)
                for(int k=0;k<6;k++)
                    dp[i][j]=min(dp[i][j],dp[i-1][k]+cmp(mp[s[i-1]],k,mp[s[i]],j));
        int minn=0x3f3f3f3f;
        for(int i=0;i<6;i++) minn=min(minn,dp[strlen(s)-1][i]);
        printf("%d\n",minn+strlen(s));
    }
    return 0;
}

J. MUV LUV EXTRA

题意:

思路:
kmp
求小数部分后 \(k\) 位的真前后缀 倒着 kmp 就好
代码:

[]

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N=1e7+5;

char s[N];
ll nxt[N];
int len;

void getNext()
{
    int i=0;
    int j=-1;
    nxt[0]=-1;
    while(i<len)
    {
        if(j==-1||s[i]==s[j])
        {
            i++,j++;
            nxt[i]=j;
        }
        else j=nxt[j];
    }
}
int main()
{
    int a,b;
    while(~scanf("%lld%lld",&a,&b))
    {
        scanf("%s",s);
        sscanf(s,"%*[^.].%s",s);
        len=strlen(s);
        reverse(s,s+len);
        getNext();
        ll ans=a-b;
        for(ll i=2;i<=len;i++) ans=max(ans,a*i-b*(i-nxt[i]));
        printf("%lld\n",ans);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/c4Lnn/p/12320955.html

时间: 2024-11-04 04:42:55

2019CCPC秦皇岛赛区的相关文章

2019-ccpc秦皇岛现场赛

https://www.cnblogs.com/31415926535x/p/11625462.html 昨天和队友模拟了下今年秦皇岛的区域赛,,,(我全程在演 题目链接 D - Decimal 签到题,,,(感觉在cf上做过,, (然后写反输出白白wa一发,,,,,emmmmmmmm F - Forest Program 这题我感觉是第二道签到题,,,很简单,,但是我一个人读完题后就想着怎么写代码,,,然后wa了无数发才反应过来还要考虑树边的情况,,,丧失理智 ,,,, 题意就是给一个 仙人掌

2019CCPC秦皇岛 I Invoker

题意: 就是魔法召唤技能,最少的符号数之类的. 思路: 线性dp题 记 dp[i][6] 为祈唤出第 i 个技能之后,身上三个法球的先后顺 序为 0 ∼ 5 的状态的最少按键数.(就是一种技能的三个发球的排列总数为6) 转移就暴力枚举上一个技能的结尾状态,然后算一下有几个 法球是可以重复使用的,取个最优值就行了. 预处理一下第i种技能的排列为z1的时候转移到第j种技能状态为z2需要的步数数组dis 写一下全排列,然后多写函数结构化程序,实现也是较为简单的. 代码: #define _CRT_SE

Forest Program(2019ccpc秦皇岛F)

题:http://acm.hdu.edu.cn/showproblem.php?pid=6736 题意:删掉一些边使得图不存在点双,求方案数. 分析:若一条边不属于点双,那么这条边有删和不删俩种选择,若找到点双,点双中必须删掉一条边(题目有保证一条边只能属于一个点双,所以不用担心一条边用于多个点双)tarjan找点双,若为点双则必须删掉点双中的一条边 #include<bits/stdc++.h> using namespace std; typedef long long ll; #defi

【2019CCPC秦皇岛:A】Angle Beats 分类讨论 (unordered_map 加 hash)

题意:n个给定点,q个询问点,每次询问给出一个坐标A,问从n中选定两个点B,C,有多少种方案使得ABC是个直角三角形. 思路:直角三角形能想的就那几个,枚举边,枚举顶点,这个题都行,写的枚举顶点的,A点分两种情况,1是直角,2是非直角.防止误差,用分数表示斜率,然后用了map<pair<int,int> int> 发现t了,改成unordered_map发现这个unordered_map只能映射一个,即unordered_map<ll, int>,所以得用到hash,把

个人日常训练计划

日期 名称 2019-09-26 2018-2019 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2018) 2019-09-27  浅学模拟退火 2019-09-28  Codeforces 几何 1700+ pt1(5/26)+  2019CCPC秦皇岛赛区(重现赛)- 感谢东秦&复旦 2019-09-29  Codeforces 几何 1700+ pt1(11/26)+ Codeforces Roun

秦皇岛站2019CCPC A.Angel Beats

题意:平面内给定n个点,q次询问,给次给定一个点P,问这个点与平面内n个点可以组成多少直角三角形,其中(n+q)个点互不相等 思路: 分别考虑P点作直角顶点和非直角顶点.这个题思路很简单,就是看如何实现简单而且不会tle!!! 对于直角顶点和非直角顶点代码都比较简单,求后者有点离线的思想. 这里想说的就是map的用法,自定义小于运算符,使得在map中查找的时候,统一斜率的向量都会加起来,虽然在map中依然会保存多个不同的向量.(听说是现场一血的写法,中山大学大佬nb) 算法复杂度大概n*n*lo

2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛

Banana Bananas are the favoured food of monkeys. In the forest, there is a Banana Company that provides bananas from different places. The company has two lists. The first list records the types of bananas preferred by different monkeys, and the seco

2014 39th ACM-ICPC 北京赛区 总结

万万没想到,拿金了. 在经历了西安赛区的打铁经历,感觉我们已经很坦然了.怎么说呢,虽说有阴影,但那也是成长的一步.我在西安打铁之后跟队友跟姐姐说过“如果北京是铜或者铁,我就退役”.记得曾经,很多人问我要搞ACM搞到几年级.有不懂ACM有了解ACM有熟悉ACM的人.好像我只对姐姐正面回答过“看看今年打的成绩吧,感觉今年是关键”.因为大二的时候跟PZ,JM一队,那次有个银,不过主要是靠他们,而且那次也有一定的运气成分.如果今年的两次成绩的最好是银尾或以下,大概我就会退役吧.因为那样的话大概就说明我尽

2014-7-5~6 秦皇岛之旅,带思杨看大海

两天的秦皇岛之旅告一段落.开心与疲惫齐飞. 周六早晨 7:30从家出发去北京站,动车北京出发到秦皇岛.11:30到秦皇岛.一路直达,北戴河一站,再没有停过.然后34路去燕山大学-静的母校附近吃肚子,找订的宾馆.--- 他们学校对面的街道几乎被拆毁了,跟她的印象不一样了.只好另找吃的,结果把订的宾馆找到了.放行李,简单修改,就在宾馆下面的饭馆点菜吃饭.那分量,真大,三个人吃了一半,剩下的带走了,虽然最后还是被 浪费了. 吃过饭,去宾馆修改,换衣服.走路去燕大对面的海碧台海滩玩.沙滩不错.天有点多云