2019icpc西安邀请赛
来源:https://www.jisuanke.com/contest/2625?view=challenges
更新中
A.Tasks
直接贪心
代码:听说当时很多队伍提前拆题甚至上机了,所以很多0min
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
#include<functional> #define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1
#define lowbit(x) ((x)&(-x)) using namespace std; typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL; const db eps = 1e-;
const int mod = 1e9+;
const int maxn = 1e6+;
const int maxm = 6e6+;
//const int inf = 0x3f3f3f3f;
const int INF = 0x3f3f3f3f;
const int MAXN = maxn;
const int MAXM = maxm;
const db pi = acos(-1.0); int n, t;
int a[maxn];
int main() {
scanf("%d %d" ,&n ,&t);
for(int i = ; i < n; i++){
scanf("%d", &a[i]);
}
sort(a,a+n);
int tmp = ;
int ans = ;
for(int i = ; i < n; i++){
if(tmp+a[i]<=t){
tmp+=a[i];ans++;
} }printf("%d", ans);
return ;
}
C.Angel's Journey
题意:给定一个圆的圆心(rx, ry),半径r,A的坐标(rx, ry-r),B的坐标(x, y),y>ry,只能走圆上以及圆外y>ry的地方,求A到B的最短路
思路:当x<rx-r或x>rx+r的时候直接从半圆的地方走直线,否则在圆弧上走到切点然后走直线
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
#include<functional> #define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1
#define lowbit(x) ((x)&(-x)) using namespace std; typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL; const db eps = 1e-;
const int mod = 1e9+;
const int maxn = 1e6+;
const int maxm = 6e6+;
//const int inf = 0x3f3f3f3f;
const int INF = 0x3f3f3f3f;
const int MAXN = maxn;
const int MAXM = maxm;
const db pi = acos(-1.0); int n, t;
int a[maxn];
int main() {
double rx,ry,r,x,y;
int t;
scanf("%d" ,&t);
while(t--){
scanf("%lf %lf %lf %lf %lf", &rx,&ry,&r,&x,&y); double ob = sqrt((x-rx)*(x-rx)+(y-ry)*(y-ry));
double ans = sqrt(ob*ob-r*r)+r*(pi/2.0+asin((y-ry)/ob)-acos(r/ob));
if(x<rx-r||x>rx+r){
if(x<rx-r)rx-=r;
if(x>rx+r)rx+=r;
ans=pi/+sqrt((x-rx)*(x-rx)+(y-ry)*(y-ry));
}
printf("%.4lf\n",ans);
}
return ;
}
D.Miku and Generals
题意:n个数,还有m对矛盾的数,n,m<=200,a[i]<=5e4&&(a[i]%100==0),矛盾的不能放在一堆,让你分配这两堆数(都要用完),使得两堆数的和之差最小,输出那个最大的数
思路:将矛盾的值连无向边,因为答案是保证存在的,所以对每一个连通块只有两种选法,通过dfs染色把它们提出来,就是一个背包了,由于a[i]%100==0,所以先除了最后再补俩零也不影响
代码:我tm最后才发现那个a[i]能整除100。。复杂度downdown
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
#include<functional> #define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1
#define lowbit(x) ((x)&(-x)) using namespace std; typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL; const db eps = 1e-;
const int mod = 1e9+;
const int maxn = 1e7+;
const int maxm = 6e6+;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0); int n, m;
vector<int>v[maxn/];
int vis[maxn/];
int a[maxn/];
int f[maxn]; void dfs(int x, int fa, int faa, int co){
if(vis[x]!=-)return;
if(co){
if(x!=fa){a[fa]+=a[x];a[x]=-;}
vis[x]=fa;
}
else{
if(x!=faa){a[faa]+=a[x];a[x]=-;}
vis[x]=faa;
}
int t;
if(x==fa&&v[x].size()>)t = v[x][];
else t=faa;
for(int i = ; i < (int)v[x].size(); i++){
int y = v[x][i];
if(vis[y]==-){
dfs(y,fa,t,co^);
} }
}
bool cmp(int a,int b){return a>b;}
int main() {
int t;
scanf("%d" ,&t);
int ncase = ;
while(t--){
scanf("%d %d" ,&n, &m);
//mem(f,0);
ncase++;
int sum = ;
for(int i = ; i <= n; i++){
v[i].clear();
vis[i]=-;
scanf("%d", &a[i]);a[i]/=;sum+=a[i];
}
for(int i = ; i <= m; i++){
int x,y;
scanf("%d %d" ,&x, &y);
v[x].pb(y);
v[y].pb(x);
}
for(int i = ; i <= n; i++){
if(vis[i]==-){
dfs(i,i,,);
}
}
sort(a+,a++n,cmp);
int ans=;
f[]=ncase;
for(int i = ; i <= n; i++){
if(a[i]==-)break;
for(int j = sum; j >= ; j--){
if(j-a[i]>=&&f[j-a[i]]==ncase){
//printf(" %d \n",j);
f[j]=ncase;
if(j<=sum/)ans=max(ans,j);
}
}
}
printf("%d00\n",sum-ans);
} return ;
}
J.And And And
题意:一棵有边权的树,对每一对(u,v),如果u到v路径上边权异或和为0,则它对答案的贡献为包含这条路径的树上路径数量,求总答案
思路:以1为根,预处理出各个子树的size,对每一对满足条件的(u,v),因为树上的路径是唯一的,它的贡献应该是u除这条路径外能走的点数*v除这条路径外能走的点数,当u和v在不同链上的时候,答案就是size[u]*size[v];若u和v在同一条链上,其中一个点(例如v)如果是深度较大的点,那么后者就是size[v],前者可以动态统计。
于是可以直接dfs,因为dfs的时候走下来就是一条链,回溯之后就是另一条链,所以在处理同一条链的时候我们可以统计当前点为u时的贡献即可。不同链的时候,我们让它dfs到底,当当前点处理完之后,说明这条链搞完了,就可以一条链一条链更新了,这个看代码好像比较好理解。。。
对了,u到v路径异或和为0可以转化为到根的异或和相等。
代码:long long很烦,而且深搜好像并不需要记录fa。。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
#include<functional>
#include<unordered_map> #define fst first
#define sc second
#define pb push_back
#define mp make_pair
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1
#define lowbit(x) ((x)&(-x)) using namespace std; typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL; const db eps = 1e-;
const int mod = 1e9+;
const int maxn = 1e5+;
const int maxm = 6e6+;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0); int n;
vector<pair<int,ll> >v[maxn];
int sz[maxn];
void dfsInit(int x, int fa){
sz[x]++;
for(int i = ; i < (int)v[x].size(); i++){
int y = v[x][i].fst;
if(y!=fa){
dfsInit(y,x);
sz[x]+=sz[y];
}
}
}
ll ans;
unordered_map<ll,int> num;// the value of gongxian in sta == i
ll tmp;
void dfs1(int x, int fa, ll sum){//the same line
ans += 1ll*num[sum]*sz[x];
ans%=mod;
for(int i = ; i < (int)v[x].size(); i++){
int y = v[x][i].fst;
ll w = v[x][i].sc;
if(y!=fa){
tmp=(tmp+sz[x]-sz[y]+mod)%mod;
num[sum]=(num[sum]+tmp)%mod;
dfs1(y,x,sum^w);
num[sum]=(num[sum]-tmp+mod)%mod;
tmp=(tmp-(sz[x]-sz[y])+mod)%mod;
}
}
}
void dfs2(int x, int fa, ll sum){
ans += 1ll*num[sum]*sz[x];
ans%=mod;
for(int i = ; i < (int)v[x].size(); i++){
int y = v[x][i].fst;
ll w = v[x][i].sc;
if(y==fa)continue;
dfs2(y,x,sum^w);
}
num[sum]+=sz[x];
num[sum]%=mod;
}
int main() {
tmp=ans=;
scanf("%d" ,&n);
for(ll i = ; i <= n; i++){
int x;
ll w;
scanf("%d %lld", &x, &w);
v[x].pb(mp(i,w));
v[i].pb(mp(x,w));
}
dfsInit(,);
dfs1(,,);
num.clear();
dfs2(,,);
printf("%lld",ans);
return ;
}
L.Swap
题意:一个排列可以交换前n/2与后n/2,或前n^1个数奇数位置和偶数位置交换,问通过这两个操作最多产生多少个不同的排列
思路:打表发现从第五项开始是2n, n, 12, 4的规律。或者直接交上打表的模拟,由于只有两条链,而且只有一组数据,也能过
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
#include<functional> #define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1
#define lowbit(x) ((x)&(-x)) using namespace std; typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL; const db eps = 1e-;
const int mod = 1e9+;
const int maxn = 1e6+;
const int maxm = 6e6+;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0); int n;
int a[maxn],b[maxn];
int ans;
void gao1(int a[]){
int l = ;
int r = n/+;
if(n&)r++;
for(int i = ; i <= n/; i++){
swap(a[l+i-],a[r+i-]);
}
return;
}
void gao2(int a[]){
for(int i = ; i+ <= n; i+=){
//printf(" %d %d %d\n",i,a[i],a[i+1]);
swap(a[i],a[i+]);
}
return;
} int sv(int n){
::n=n;
ans=;
int sta=;
for(int i = ; i <= n; i++)a[i]=b[i]=i;
/*if(n==1)return 1;
if(n==2)return 2;
if(n==3)return 6;*/
gao1(a);gao2(b);
//for(int i = 1; i <= n; i++)printf("%d ",a[i]);printf("\n");
//for(int i = 1; i <= n; i++)printf("%d ",b[i]);printf("\n");
while(){
//for(int i = 1; i <= n; i++)printf("%d ",a[i]);printf("\n");
//for(int i = 1; i <= n; i++)printf("%d ",b[i]);printf("\n");
int ys = ;
sta^=;
for(int i = ; i <= n; i++){
if(a[i]!=b[i])ys=;
}
if(!ys){
ans++;break;
}
else{
ans+=;
if(sta) {gao1(a);gao2(b);}
else {gao1(b);gao2(a);}
}
}
return ans;
}
int main() {
//scanf("%d" ,&n);
//sv(3);
for(int i = ; i <= ; i++){
printf("%d %d\n",i,sv(i));
}
scanf("%d", &n);
//for(int i = 1; i <= n; i++)scanf("%d", &a[i]);
printf("%d",sv(n));
return ;
}
M.Travel
题意:一个有边权的无向图,刚开始无边可走,每次操作可以增加e条边,增加d点能量,每次操作花费c,问从1走到n最少花费多少,只有这条边加了并且能量不小于边权才能走
思路:我第n次sb。。很明显的二分,而我妄图一次dijk搞完,就把自己搞完了。
很显然操作次数具有单调性,并且因为保证联通,所以答案一定存在。
代码:因为改了很多次,所以很丑
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
#include<functional> #define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1
#define lowbit(x) ((x)&(-x)) using namespace std; typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL; const db eps = 1e-;
const int mod = 1e9+;
const int maxn = 1e6+;
const int maxm = 6e6+;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0); int vis[maxn];
struct node{
int id,w;
node(int a, int b){id=a;w=b;}
bool operator < (const node & a) const{
return w>a.w;
}
};
vector<node>v[maxn];
int n,m;
int c, d, e;
bool ck(int k){
//printf(" %d\n",k);
for(int i = ; i <= n; i++)vis[i]=;
queue<PI>q;
q.push(make_pair(,));
while(!q.empty()){
PI top = q.front();q.pop();
int x = top.fst;
int d = top.sc;
//printf("%d %d ----%d\n",x,d);
if(x==n){
if(d<=1ll*e*k)return true;
else return false;
}
if(vis[x])continue;
vis[x]=;
for(int i = ; i < (int)v[x].size(); i++){
node y = v[x][i];
//printf(" %d %d\n",y.id,y.w);
if(!vis[y.id]&&1ll*y.w<=1ll*(::d)*k)q.push(make_pair(y.id,d+));
}
}
return false;
}
int main() { scanf("%d %d", &n, &m);
scanf("%d %d %d" ,&c, &d, &e);
for(int i = ; i <= m; i++){
int x,y,w;
scanf("%d %d %d" ,&x, &y, &w);
v[x].pb(node(y,w));
v[y].pb(node(x,w));
}
int l, r;
l = ; r = 1e5+;
int ans = -;
while(l<=r){
int mid = (l+r)>>;
if(ck(mid)){
ans = mid;
r=mid-;
}
else l= mid+;
}
printf("%lld",1ll*c*ans);
return ;
}
/*
3 3
1 99 1
1 2 100
1 3 100
2 3 2
*/
2019icpc西安邀请赛的更多相关文章
- 计蒜客 39272.Tree-树链剖分(点权)+带修改区间异或和 (The 2019 ACM-ICPC China Shannxi Provincial Programming Contest E.) 2019ICPC西安邀请赛现场赛重现赛
Tree Ming and Hong are playing a simple game called nim game. They have nn piles of stones numbered ...
- 2019ICPC西安邀请赛 - B. Product - 数论
打印的时候麻烦把:https://blog.csdn.net/skywalkert/article/details/50500009这个打印下来. 求\(\prod\limits_{i=1}^{n} ...
- 2019ICPC西安邀请赛(计蒜客复现赛)总结
开始时因为吃饭晚了一刻钟,然后打开比赛.看了眼榜单A题已经过了二十来个队伍了,宝儿就去做A. 传师说最后一题看题目像最短路,于是我就去看M了,宝儿做完之后也来陪我看.M一开始看到时以为是像 POJ ...
- 计蒜客 39280.Travel-二分+最短路dijkstra-二分过程中保存结果,因为二分完最后的不一定是结果 (The 2019 ACM-ICPC China Shannxi Provincial Programming Contest M.) 2019ICPC西安邀请赛现场赛重现赛
Travel There are nn planets in the MOT galaxy, and each planet has a unique number from 1 \sim n1∼n. ...
- 计蒜客 39279.Swap-打表找规律 (The 2019 ACM-ICPC China Shannxi Provincial Programming Contest L.) 2019ICPC西安邀请赛现场赛重现赛
Swap There is a sequence of numbers of length nn, and each number in the sequence is different. Ther ...
- 计蒜客 39270.Angel's Journey-简单的计算几何 ((The 2019 ACM-ICPC China Shannxi Provincial Programming Contest C.) 2019ICPC西安邀请赛现场赛重现赛
Angel's Journey “Miyane!” This day Hana asks Miyako for help again. Hana plays the part of angel on ...
- 计蒜客 39268.Tasks-签到 (The 2019 ACM-ICPC China Shannxi Provincial Programming Contest A.) 2019ICPC西安邀请赛现场赛重现赛
Tasks It's too late now, but you still have too much work to do. There are nn tasks on your list. Th ...
- 2019icpc西安邀请赛 J And And And (树形dp)
题目链接:https://nanti.jisuanke.com/t/39277 题意:给出一棵有边权的树,求所有简单路径包含异或和为0的简单路径的总数和. 思路: 首先,对于异或为0这一限制,我们通过 ...
- 【2019ICPC西安邀请赛】J.And And And(点分治,贡献)
题意:给定一棵n个点带边权的树,定义每条路径的值为路径上边权的异或和 如果一条路径的值为0,其对答案的贡献为所有包含这条路径的路径条数 求答案膜1e9+7 n<=1e5,0<=边权< ...
随机推荐
- Flink系列之Time和WaterMark
当数据进入Flink的时候,数据需要带入相应的时间,根据相应的时间进行处理. 让咱们想象一个场景,有一个队列,分别带着指定的时间,那么处理的时候,需要根据相应的时间进行处理,比如:统计最近五分钟的访问 ...
- MakeDown效果
这是一级标题 这是二级标题 这是三级标题 这是四级标题 这是五级标题 这是六级标题 这是加粗的文字 这是倾斜的文字 这是斜体加粗的文字 这是加删除线的文字 这是引用的内容 这是引用的内容 这是引用的内 ...
- Go Web 编程之 响应
概述 上一篇文章中,我们介绍了请求的结构与处理.本文将详细介绍如何响应客户端的请求.其实在前面几篇文章中,我们已经使用过响应的功能--通过http.ResponseWriter发送字符串给客户端. 但 ...
- CSP-S rp++
心无旁骛 认真思考 努力骗分(哈哈) I Love CSP! 反正像我这种大菜鸟也考不了多少 尽力打 本次考试期望 day1 100 70-100 30-? day2 100 ? ? 总:300-? ...
- win10内存泄漏怎么办
我的电脑莫名的内存占用越来越高,但是实际内存很低 查了很多资料 下边是我找到的最有效的方法: 原因:是系统自带的网络数据监控和和Killer网卡的监控程序冲突,导致 非页面缓存无法释放. 解决方法:解 ...
- 查看JVM参数
如何查看一个正在运行中的java程序,它的某个jvm参数是否开启?具体值是多少? jps jinfo jvm的参数类型: 1.标配参数:java -version ,java -help , jav ...
- Scrapy定制命令开启爬虫
一.单爬虫运行 每次运行scrapy都要在终端输入命令太麻烦了 在项目的目录下创建manager.py(任意名称) from scrapy.cmdline import execute if __na ...
- Educational Codeforces Round 80 (Rated for Div. 2) E. Messenger Simulator
可以推出 min[i]要么是i要么是1,当a序列中存在这个数是1 max[i]的话就比较麻烦了 首先对于i来说,如果还没有被提到第一位的话,他的max可由他后面的这部分序列中 j>=i 的不同数 ...
- Python处理URL编码
我们在访问网站时,有很多连接都是有一些特殊符号组成,例如,我在百度搜索“大鱼海棠”,结果可以看到它的搜索出来的链接是: https://www.baidu.com/s?wd=%E5%A4%A7%E9% ...
- RestTemplate---Spring提供的轻量Http Rest 风格API调用工具
前言 今天在学习Spring Cloud的过程中无意发现了 RestTemplate 这个Spring 提供的Http Rest风格接口之间调用的模板工具类,感觉比Apache提供的HttpClien ...