来源: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西安邀请赛的更多相关文章

  1. 计蒜客 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  ...

  2. 2019ICPC西安邀请赛 - B. Product - 数论

    打印的时候麻烦把:https://blog.csdn.net/skywalkert/article/details/50500009这个打印下来. 求\(\prod\limits_{i=1}^{n} ...

  3. 2019ICPC西安邀请赛(计蒜客复现赛)总结

    开始时因为吃饭晚了一刻钟,然后打开比赛.看了眼榜单A题已经过了二十来个队伍了,宝儿就去做A. 传师说最后一题看题目像最短路,于是我就去看M了,宝儿做完之后也来陪我看.M一开始看到时以为是像   POJ ...

  4. 计蒜客 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. ...

  5. 计蒜客 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 ...

  6. 计蒜客 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 ...

  7. 计蒜客 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 ...

  8. 2019icpc西安邀请赛 J And And And (树形dp)

    题目链接:https://nanti.jisuanke.com/t/39277 题意:给出一棵有边权的树,求所有简单路径包含异或和为0的简单路径的总数和. 思路: 首先,对于异或为0这一限制,我们通过 ...

  9. 【2019ICPC西安邀请赛】J.And And And(点分治,贡献)

    题意:给定一棵n个点带边权的树,定义每条路径的值为路径上边权的异或和 如果一条路径的值为0,其对答案的贡献为所有包含这条路径的路径条数 求答案膜1e9+7 n<=1e5,0<=边权< ...

随机推荐

  1. 微信小程序吸顶功能

    ---------------------------HTML------------------------ <view class="navbar-wrap">  ...

  2. 手算CRC及其实现

    前言: 这篇文章主要讲的是如何手算CRC以及运用CRC,更侧重方法的步骤,对原理方面不做探讨. 方法也是按照我个人理解的来,所以并不专业~ 一些搬过来的代码我也修改了一下下 如果想了解原理的可参考资料 ...

  3. Vuex实践(下)-mapState和mapGetters

    Vuex系列文章 <Vuex实践(上)> <Vuex实践(中)-多module中的state.mutations.actions和getters> <Vuex实践(下)- ...

  4. vue超简单加载字体方法,解决scss难加载字体的问题

    vue超简单加载字体方法,解决scss难加载字体的问题 scss在加载字体方面一直不太好用,需要繁杂的配置才能达到想要的效果,这里说一种非常简单的方法 在App.vue的style标签下引入字体文件后 ...

  5. 【Magicodes.IE 2.0.0-beta1版本发布】已支持数据表格、列筛选器和Sheet拆分

    为了更好的完善Magicodes.IE,春节期间我们会进行一次大的重构.由于精力有限,急缺文档和翻译(将文档翻译为英文文档)支持,诚邀各位加入.同时在功能方便也做了相关规划,有兴趣的朋友可以参与提交P ...

  6. 《C# 爬虫 破境之道》:第一境 爬虫原理 — 第三节:WebResponse

    第二节中,我们介绍了WebRequest,它可以帮助我们发送一个请求,不过正所谓“来而不往非礼也”,对方收到我们的请求,不给点回复,貌似不太合适(不过,还真有脸皮厚的:P). 接下来,就重点研究一下, ...

  7. 打包一份py给大家用!!!

    好不容易写完了代码,却发现对面无法使用自己的python代码,其无奈可想而知 在这里就给大家介绍一下pyinstaller的简单用法 你所需要的就是在电脑上安装好 https://blog.csdn. ...

  8. Scrum.自用SCRUM项目开发流程

    目前团队所使用的开发模式流程,请大家指正优化. 1.PM需求整理:在禅道整理出需求清单和原型图(标注清楚):需求评审.往复,直到需求定稿. 2.SprintMaster根据需求清单进行技术任务拆解,包 ...

  9. [洛谷P4097] [HEOI2013] Segment

    Description 要求在平面直角坐标系下维护两个操作: 1.在平面上加入一条线段.记第 \(i\) 条被插入的线段的标号为 \(i\) 2.给定一个数 \(k\) ,询问与直线 \(x = k\ ...

  10. linux操作系统下调试python代码方法

    一.python有调试工具pdb,可以用来进行代码调试. pdb的常用命令说明: l #查看运行到哪行代码 n #单步运行,跳过函数 s #单步运行,可进入函数 p 变量 #查看变量值 b 行号 #断 ...