http://codeforces.com/contest/1184

A1

找一对整数,使x^x+2xy+x+1=r

变换成一个分式,保证整除

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include <map>
#define fo(i,l,r) for(int i = l;i <= r;i++)
#define ll long long
using namespace std;
const int maxn = 300050;
const ll mod = 1e9+7;
inline ll read(){ll 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 * 10 + ch - '0';ch = getchar();}return x * f;
}
ll r;
int main(){r=read();for(ll i = 1;i <= 1000000;i++){if(i*i>r)break;ll t = r-i*i-i-1;if(t<=0)continue;if(t%(i+i)==0){cout<<i<<" "<<t/(i+i);return 0;}}cout<<"NO";return 0;
}

View Code

A2

给定一个二进制串,对于整数k来说,若存在另一个二进制串x,时x与x右移k位异或的结果等于这个二进制串,k就是合法的,求合法的k的数量。

先考虑x,第一个位确定了,后面1+k,1+2k...的位也确定了,最后会回到第一位,这时需要与之前假定的第一位一致。于是这就形成了一个循环。循环长度为lcm(k,n)/k=n/gcd(k,n)。

对k,按gcd(k,n),进行归纳求解,将所有k映射到gcd(k,n),然后求出gcd(k,n)的答案,只需要遍历所有循环的位置,再查看是否合法。

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include <map>
#define fo(i,l,r) for(int i = l;i <= r;i++)
#define ll long long
using namespace std;
const int maxn = 200050;
const ll mod = 1e9+7;
inline ll read(){ll 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 * 10 + ch - '0';ch = getchar();}return x * f;
}
int n;
int a[maxn];
char s[maxn];
bool vis[maxn];
bool can[maxn];
int gcd(int a,int b){return b==0?a:gcd(b,a%b);
}
int main(){n=read();scanf("%s",s+1);fo(i,1,n){a[i] = s[i] - '0';}int ans = 0,tot = 0;fo(i,1,n){int g = gcd(i,n);if(vis[g]){ans += can[g];}else{vis[g]=true;bool ok=false;fo(j,1,g){ok=true;tot=0;for(int k = j;k <= n;k += g){tot += a[k];}if(tot%2){ok=false;break;}}if(ok) can[g]=true;ans += can[g];}}cout<<ans;return 0;
}

View Code

B1

舰队攻打敌军,只能攻打防御力不大于它攻击力的,敌军掉落的金币不等,问每个船能打多少钱

排序即可

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include <map>
#define fo(i,l,r) for(int i = l;i <= r;i++)
#define ll long long
using namespace std;
const int maxn = 200050;
const ll mod = 1e9+7;
inline ll read(){ll 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 * 10 + ch - '0';ch = getchar();}return x * f;
}
int s,b;
struct dat{int pos;int val;friend bool operator < (dat a,dat b){return a.val < b.val;}
}shp[maxn],ene[maxn];
ll gold[maxn];
int main(){s=read();b=read();fo(i,1,s){shp[i].pos=i;shp[i].val=read();}fo(i,1,b){ene[i].val=read();ene[i].pos=read();}sort(shp+1,shp+1+s);sort(ene+1,ene+1+b);int pos=0;ll ans = 0;fo(i,1,s){while(pos<b&&ene[pos+1].val<=shp[i].val){pos++;ans += ene[pos].pos;}gold[shp[i].pos]=ans;}fo(i,1,s){printf("%I64d ",gold[i]);}return 0;
}

View Code

B2

敌军在一个图上攻打舰队,每个敌军只能打防御力不大于他的船,并且两者距离不大于他的燃油量。每个敌军负责打一个人,掠夺k金币。

我军可以花h金币建造假船,一定会被一个敌军攻击,且不损失金币。求损失最少的策略。

因为金币数量是固定的,容易证明要么全用假船吸引,要么一个假船都不放。

先跑多源最短路,然后匹配即可。

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include <map>
#define fo(i,l,r) for(int i = l;i <= r;i++)
#define ll long long
using namespace std;
const int maxn = 200050;
const ll mod = 1e9+7;
inline ll read(){ll 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 * 10 + ch - '0';ch = getchar();}return x * f;
}
int n,m;
int dis[105][105];
int s,b;
ll kk,hh;
struct ship{int x;ll f;ll a;
}ships[1050];
struct ene{int x;ll d;
}enes[1050];
int uN,vN;
int g[1050][1050];
int linker[1050];
int used[1050];
bool dfs(int u){for(int v = 0;v < vN;v++){if(g[u][v] && !used[v]){used[v] = true;if(linker[v]==-1||dfs(linker[v])){linker[v]=u;return true;}}}return false;
}
int hungary(){int res = 0;memset(linker,-1, sizeof(linker));for(int u = 0;u < uN;u++){memset(used,false, sizeof(used));if(dfs(u))res++;}return res;
}
int main(){n=read();m=read();int u,v;fo(i,1,n){fo(j,1,n){dis[i][j]=1e7;}dis[i][i]=0;}fo(i,1,m){u=read();v=read();dis[u][v] = 1;}fo(k,1,n){fo(i,1,n){fo(j,1,n){if(k==i||k==j||i==j)continue;dis[i][j] = min(dis[i][j],dis[i][k]+dis[k][j]);}}}s=read();b=read();kk=read();hh=read();fo(i,1,s){ships[i].x=read();ships[i].a=read();ships[i].f=read();}fo(i,1,b){enes[i].x=read();enes[i].d=read();}uN=s;vN=b;fo(i,1,s){fo(j,1,b){if(ships[i].a >= enes[j].d && dis[ships[i].x][ships[j].x] <= ships[i].f) g[i-1][j-1]=1;}}ll ans = min((ll)s*hh,kk*hungary());cout<<ans;return 0;
}

View Code

C1

给若干个在长方形边上的点和一个不在边上的点,找出那个长方形

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include <map>
#define fo(i,l,r) for(int i = l;i <= r;i++)
#define ll long long
using namespace std;
const int maxn = 55;
const ll mod = 1e9+7;
inline ll read(){ll 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 * 10 + ch - '0';ch = getchar();}return x * f;
}
int n;
int x[maxn],y[maxn];
bool check(int x1,int x2,int y1,int y2){int cnt = 0,t=0;bool debug=false;if(x1==19&&x2==45&&y1==1&&y2==27)debug=true;fo(i,1,n){if(x[i]<x1||x[i]>x2||y[i]<y1||y[i]>y2){cnt++;t=i;}else if(x[i]!=x1&&x[i]!=x2&&y[i]!=y1&&y[i]!=y2){cnt++;t=i;}if(cnt>1)return false;}if(cnt == 0) return false;cout<<x[t]<<" "<<y[t];return true;
}
int main(){n=read();n = n*4+1;fo(i,1,n){x[i]=read();y[i]=read();}fo(i,0,50){fo(j,i,50){fo(k,0,50){fo(l,k,50){if(check(i,j,k,l)) return 0;}}}}return 0;
}

View Code

D1

一个长度n的线段和一个特殊点,每次插入或者切掉头或尾一段,每次询问特殊点的位置。

维护即可。

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include <map>
#define fo(i,l,r) for(int i = l;i <= r;i++)
#define ll long long
using namespace std;
const int maxn = 305;
const ll mod = 1e9+7;
inline ll read(){ll 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 * 10 + ch - '0';ch = getchar();}return x * f;
}
int n,k,m,t;
int main(){n=read();k=read();m=read();t=read();int opt,v;fo(i,1,t){opt=read();v=read();if(opt==1){n++;if(v<=k)k++;}else{if(k > v){n-=v;k-=v;}else{n=v;}}cout<<n<<" "<<k<<endl;}return 0;
}

View Code

E1

给一个图,求出最小生成树,问如果第一条边可能在最小生成树里,其边权最多是多大

看看什么时候这条边对应的两个点处于同一个集合中。

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include <map>
#define fo(i,l,r) for(int i = l;i <= r;i++)
#define ll long long
using namespace std;
const int maxn = 100050;
const ll mod = 1e9+7;
inline ll read(){ll 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 * 10 + ch - '0';ch = getchar();}return x * f;
}
int n,m;
int f[maxn];
int findf(int x){return f[x]==x?x:f[x]=findf(f[x]);
}
struct edge{int u;int v;ll w;friend bool operator < (edge a,edge b){return a.w < b.w;}
}e[maxn*10];
int main(){n=read();m=read();fo(i,1,m){e[i].u=read();e[i].v=read();e[i].w=read();}fo(i,1,n){f[i]=i;}int aa = e[1].u,bb=e[1].v;sort(e+1,e+1+m);fo(i,1,m){int u=e[i].u;int v=e[i].v;int fu=findf(u),fv=findf(v);if(fu==fv) continue;if(e[i].u==aa&&e[i].v==bb)continue;f[fu]=fv;if(findf(aa)==findf(bb)){cout<<e[i].w;return 0;}}cout<<1000000000;return 0;
}

View Code

E2

与上一个问题类似,但是这次要求除了最小生成树的边之外所有边的答案

先求最小生成树,两个点之间加一条边,则形成一个环,由这条边和两者的树上最短路径的边组成,用lca求最短路径上的边的最大边权即可。

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include <map>
#define fo(i,l,r) for(int i = l;i <= r;i++)
#define ll long long
using namespace std;
const int maxn = 100050;
const ll mod = 1e9+7;
inline ll read(){ll 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 * 10 + ch - '0';ch = getchar();}return x * f;
}
int n,m;
int f[maxn];
int findf(int x){return f[x]==x?x:f[x]=findf(f[x]);
}
struct edge{int u;int v;ll w;int id;friend bool operator < (edge a,edge b){return a.w < b.w;}
}e[maxn*10];
bool chs[maxn*10];
bool cmp(edge a,edge b){return a.id < b.id;
}
int dep[maxn];
int fa[maxn][25];
ll fw[maxn][25];
struct te{int v;ll w;
}now,nxt;
vector<te> g[maxn];
void dfs(int x,int p){int k = 0;   while(fa[x][k]&&fa[fa[x][k]][k]){fa[x][k+1] = fa[fa[x][k]][k];fw[x][k+1] = max(fw[x][k],fw[fa[x][k]][k]);k++;}int sz = g[x].size();int v=0;fo(i,0,sz-1){v=g[x][i].v;if(v==p)continue;fa[v][0] = x;fw[v][0] = g[x][i].w;dep[v] = dep[x] + 1;dfs(v,x);}
}
ll getans(int u,int v){if(dep[u]<dep[v]) swap(u,v);ll mx = 0;int k = 0,dif=dep[u]-dep[v];int ru=u,rv=v;while(dif){if(dif&1){mx = max(fw[u][k],mx);u = fa[u][k];}dif >>= 1;k++;}if(u==v)return mx;k = 0;while(k >= 0){if(fa[u][k] != fa[v][k]){mx = max(mx,fw[u][k]);mx = max(mx,fw[v][k]);u = fa[u][k];v = fa[v][k];k++;}else{k--;}}mx = max(mx,fw[u][0]);mx = max(mx,fw[v][0]);return mx;
}
int main(){n=read();m=read();fo(i,1,m){e[i].u=read();e[i].v=read();e[i].w=read();e[i].id=i;}fo(i,1,n){f[i]=i;}sort(e+1,e+1+m);fo(i,1,m){int u=e[i].u;int v=e[i].v;int fu=findf(u),fv=findf(v);if(fu==fv) continue;f[fu]=fv;chs[e[i].id]=true;now.w=e[i].w;now.v=v;g[u].push_back(now);now.v=u;g[v].push_back(now);}dfs(1,0);sort(e+1,e+1+m,cmp);fo(i,1,m){if(chs[i])continue;printf("%I64d\n",getans(e[i].u,e[i].v));}return 0;
}

View Code

转载于:https://www.cnblogs.com/hyfer/p/11165349.html

Helvetic Coding Contest 2019 online mirror (teams allowed, unrated)相关推荐

  1. Helvetic Coding Contest 2018 online mirror (teams allowed, unrated) C2.Encryption (medium)

    传送门:Encryption(medium) 题意:N个数,分成k个连续的序列,把每个序列的数累加取模p,求k个取模结果累加的最大值. 分析:DP, 复杂度O(Nkp) 设dp[i][j]为取模结果i ...

  2. CF 690C3. Brain Network (hard) from Helvetic Coding Contest 2016 online mirror (teams, unrated)

    题目描述 Brain Network (hard) 这个问题就是给出一个不断加边的树,保证每一次加边之后都只有一个连通块(每一次连的点都是之前出现过的),问每一次加边之后树的直径. 算法 每一次增加一 ...

  3. 【HDU - 5988】Coding Contest(网络流费用流,改模板)

    题干: A coding contest will be held in this university, in a huge playground. The whole playground wou ...

  4. Coding Contest HDU - 5988

    Coding Contest HDU - 5988 题意: 有n个点,m个边,每个点有人数和食物数,每个人都要吃一份食物,如果该点的食物不够,他们就要去其他点,每个边最多只能走c次,每次有人走一条路, ...

  5. 2021年度训练联盟热身训练赛第二场(ICPC North Central NA Contest 2019,南阳师范学院),签到题ABCDEFGIJ

    A. Binarize It,简单枚举 链接:https://ac.nowcoder.com/acm/contest/12794/A 来源:牛客网 题目描述 Professor Boolando ca ...

  6. Central Europe Regional Contest 2019 J. Saba1000kg (并查集+根号讨论)

    链接:https://ac.nowcoder.com/acm/contest/7817/I 来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言524 ...

  7. 【最小费用最大流(改进Dijkstra)】2016 icpc 青岛 G - Coding Contest

    题目:https://vjudge.net/contest/412116#problem/G 题意:t组样例,n个点,每个点有sis_isi​个人和bib_ibi​份物资.m条边,每条边从第二次开始, ...

  8. Yahoo Programming Contest 2019 F - Pass

    传送门 题目大意 给定一个只包含012序列,0表示这个人有2个红球,1表示一个红球一个蓝球,2表示两个蓝球.进行n*2次游戏,每次游戏所有有球的人选择一个球递给前一个人,第一个人把球放到一个序列中,' ...

  9. HDU - 5988 Coding Contest(最大费用最大流+思维建边)

    题目链接:点击查看 题目大意:给出n个点和m条边,每个点有ai个人和bi份食物,每条边最多能通过ci个人,以及除了第一个人之外,其他人通过每条边触电的概率为pi,在以上约束下,要求每个人都必须吃到一份 ...

最新文章

  1. golang json 读写配置文件
  2. Hive之DDL数据操作
  3. python地图 两点距离_没学过还真不会!怎样才能画出准确的地图?
  4. 将域名绑定到ip上,并实现访问不同二级子域名对应不同目录
  5. 如何设置Linux操作系统shell命令的默认语言
  6. 敏捷数据科学pdf_敏捷数据科学数据科学可以并且应该是敏捷的
  7. supervisord安装使用简记
  8. 我写了一个开源项目AlphabetPy
  9. golang结构体tag的使用
  10. python 彩票分析_294期钱哥福彩3D预测奖号:杀号分析
  11. 2018年山西省环境空气质量综合指数平均下降10.8%
  12. 阶段3 1.Mybatis_06.使用Mybatis完成DAO层的开发_8 properties标签的使用及细节
  13. 我的世界服务器怎么显示玩家和怪,我的世界怎样用指令来让怪物不攻击玩家 | 手游网游页游攻略大全...
  14. ubuntu安装配置搜狗拼音输入法
  15. 几个不知道算不算经典的游戏
  16. windows无法访问指定计算机,windows无法访问指定设备路径或文件的解决方法
  17. [Linux] Linux中/tmp目录下文件莫名丢失
  18. android屏幕分辨率适配总结
  19. 解决fullpage尾屏半屏问题
  20. java 水印处理_java 图片水印处理

热门文章

  1. 深入浅出解释 FFT(一)—— 用 fft 求频谱
  2. 计算机项目:国际象棋
  3. OpenCV视频生成
  4. 【Linux】linux权限设置
  5. OpenFlow交换机概述
  6. Java回调的四种写法(反射、直接调用、接口调用、Lamda表达式)
  7. codeforces 1181C
  8. Nmap使用教程超超超详细——最后介绍绕过防火墙IDS逃逸
  9. Pycharm 修改html注释
  10. js获取classname值_getElementsByClassName的用法 和 js获取class