2016-2017 ACM-ICPC Asia-Bangkok Regional Contest
A. WSI Extreme
将人按洗澡时间从大到小排序,那么$ans=\sum_{i=1}^{n}a_i\times\lfloor\frac{i+W-1}{W}\rfloor$。
当$W$比较大时,暴力枚举每一段,然后求和即可,权值线段树维护。
当$W$比较小时,线段树上按排名模$W$的值维护$W$个量即可。
时间复杂度$O(q\sqrt{W}\log n)$。
B. Average
枚举平均数然后容斥+隔板法计算方案数即可。
#include <bits/stdc++.h>
using namespace std ; typedef long long LL ;
const int mod=1e9+7,Maxn=60*202;
void up(int &x,int y){x+=y;if(x>=mod)x-=mod;}
int rev[Maxn],fac[Maxn];
int C(int x,int y){
if(x<y||y<0)return 0;
return 1LL*fac[x]*rev[y]%mod*rev[x-y]%mod;
}
void solve(){
fac[0]=fac[1]=rev[0]=rev[1]=1;
for(int i=2;i<Maxn;i++)fac[i]=1LL*fac[i-1]*i%mod;
for(int i=2;i<Maxn;i++)rev[i]=1LL*(mod-mod/i)*rev[mod%i]%mod;
for(int i=2;i<Maxn;i++)rev[i]=1LL*rev[i-1]*rev[i]%mod;
}
int check(int sum,int n,int m){
int ret=0;
for(int i=0;i<=n;i++){
int tmp=1LL*C(n,i)*C(sum+n-i*(m+1)-1,n-1)%mod;
//if(i==1)printf("t1=%d t2=%d\n",C(n,i),C(sum+n-i*(m+1)-1,n-1));
if(i&1)tmp=(mod-tmp)%mod;
up(ret,tmp);
//printf("ret=%d\n",ret);
}
return ret;
}
int main () {
solve(); //printf("t2=%d\n",check(2,2,1));
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
if(!n&&!m)break;
int ans=0;
for(int i=0;i<=m;i++){
up(ans,1LL*check((n-1)*i,n-1,m)%mod);
}
//printf("t1=%d\n",check(0,2,1)); //printf("t2=%d\n",check(2,2,1));
ans=1LL*ans*n%mod;
printf("%d\n",ans);
}
return 0 ;
}
C. Big Bang
$ans=\sum_{i=1}^n\mu(i)\lfloor\frac{n}{i}\rfloor^4$。
D. Find C
首先通过exgcd求出一组解,然后往两侧延伸$K$个即可。
#include <bits/stdc++.h>
using namespace std ; typedef long long LL ;
const LL LIM=100000000000000LL;
typedef pair<LL,LL>pi;
LL sx,sy,ex,ey;
int K;
LL gcd(LL x,LL y){
if(!x)return y;
if(!y)return x;
return __gcd(x,y);
}
inline LL exgcd(LL a,LL b,LL &x,LL &y){
if(!b)return x=1,y=0,a;
LL d=exgcd(b,a%b,y,x);
y-=a/b*x;
return d;
}
int ok(LL x,LL y){
if(abs(x)>LIM||abs(y)>LIM)return 0;
return 1;
}
bool check(LL x,LL y){
if(x==sx&&y==sy)return 0;
if(x==ex&&y==ey)return 0;
if(__gcd(abs(x-sx),abs(y-sy))>1)return 0;
if(__gcd(abs(x-ex),abs(y-ey))>1)return 0;
return 1;
}
/*
void getst(LL &x,LL &y,LL stepx,LL stepy){
if(!stepx){
if(stepy<0){
y%=-stepy;
}
else {
y%=stepy;
}
}
else
if(!stepy){
x%=stepx;
}
else{
if(stepy>0){
LL
}
}
}
*/
set<pi>res;
void solve(LL S){
LL A=abs(sy-ey),B=abs(sx-ex);
LL gc=gcd(A,B);
LL tA=(sy-ey)/gc,tB=(ex-sx)/gc;
LL ftA=abs(tA),ftB=abs(tB);
LL C=S-(sx*ey-ex*sy);
C/=gc;
LL x,y;
exgcd(ftA,ftB,x,y);
if(ftB){
x=x*(C%ftB)%ftB;
y=(C-x*ftA)/ftB;
}
else{
y=y*(C%ftA)%ftA;
x=(C-y*ftB)/ftA;
}
if(tA<0)x=-x;
if(tB<0)y=-y;
LL stepx=(ex-sx)/gc,stepy=(ey-sy)/gc;
//if(!ok(x,y))while(1);
for(LL curx=x+stepx,cury=y+stepy;res.size()<K&&ok(curx,cury);curx+=stepx,cury+=stepy){
if(check(curx,cury)){
//printf("curx=%lld cury=%lld\n",curx,cury);
res.insert(pi(curx,cury));
}
} for(LL curx=x,cury=y;res.size()<K&&ok(curx,cury);curx-=stepx,cury-=stepy){
if(check(curx,cury)){
res.insert(pi(curx,cury));
}
}
}
int main () {
int _;scanf("%d",&_);
while(_--){
scanf("%lld%lld%lld%lld%d",&sx,&sy,&ex,&ey,&K);
if(ex<sx){swap(sx,ex);swap(sy,ey);}
res.clear();
LL S=__gcd(abs(sx-ex),abs(sy-ey));
solve(S);
solve(-S);
if(res.size()<K)while(1);
for(set<pi>::iterator it=res.begin();it!=res.end();it++){
printf("%lld %lld\n",it->first,it->second);
}
}
return 0 ;
}
E. ACM Tax
可持久化线段树维护即可。
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=50010,M=N*20;
int T,C;
int n,m,i,x,y,z,g[N],v[N<<1],w[N<<1],nxt[N<<1],ed;
int f[N],d[N],size[N],son[N],top[N];
int tot,rt[N],l[M],r[M],val[M];
inline void add(int x,int y,int z){v[++ed]=y;w[ed]=z;nxt[ed]=g[x];g[x]=ed;}
int ins(int x,int a,int b,int c){
int y=++tot;
val[y]=val[x]+1;
if(a==b)return y;
int mid=(a+b)>>1;
if(c<=mid){
l[y]=ins(l[x],a,mid,c);
r[y]=r[x];
}else{
l[y]=l[x];
r[y]=ins(r[x],mid+1,b,c);
}
return y;
}
void dfs(int x){
size[x]=1;
for(int i=g[x];i;i=nxt[i])if(v[i]!=f[x]){
f[v[i]]=x,d[v[i]]=d[x]+1;
rt[v[i]]=ins(rt[x],1,100000,w[i]);
dfs(v[i]),size[x]+=size[v[i]];
if(size[v[i]]>size[son[x]])son[x]=v[i];
}
}
void dfs2(int x,int y){
top[x]=y;
if(son[x])dfs2(son[x],y);
for(int i=g[x];i;i=nxt[i])if(v[i]!=son[x]&&v[i]!=f[x])dfs2(v[i],v[i]);
}
inline int lca(int x,int y){
for(;top[x]!=top[y];x=f[top[x]])if(d[top[x]]<d[top[y]])swap(x,y);
return d[x]<d[y]?x:y;
}
inline int kth(int x,int y,int z,int k){
int a=1,b=100000,mid,t;
while(a<b){
mid=(a+b)>>1;
t=val[l[x]]+val[l[y]]-2*val[l[z]];
if(k<=t){
b=mid;
x=l[x];
y=l[y];
z=l[z];
}else{
k-=t;
a=mid+1;
x=r[x];
y=r[y];
z=r[z];
}
}
return a;
}
inline int query(int x,int y){
int z=lca(x,y);
int all=d[x]+d[y]-d[z]*2;
if(all&1)return kth(rt[x],rt[y],rt[z],(all+1)/2)*2;
return kth(rt[x],rt[y],rt[z],all/2)+kth(rt[x],rt[y],rt[z],all/2+1);
}
int main(){
scanf("%d",&T);
for(C=1;C<=T;C++){
scanf("%d",&n);
ed=0;
for(i=1;i<=n;i++)g[i]=f[i]=d[i]=size[i]=son[i]=top[i]=rt[i]=0;
for(i=1;i<n;i++)scanf("%d%d%d",&x,&y,&z),add(x,y,z),add(y,x,z);
dfs(1);
dfs2(1,1);
scanf("%d",&m);
while(m--)scanf("%d%d",&x,&y),printf("%.1f\n",0.5*query(x,y));
for(i=1;i<=tot;i++)l[i]=r[i]=val[i]=0;
tot=0;
}
}
F. Dictionary Game
建出Trie树,然后就是经典树上删边游戏。
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=100010*40;
int T,C,tot,son[N][26],sg[N],f[N];
int n,i,j;
inline int ins(){
static char s[99];
scanf("%s",s);
int l=strlen(s);
int x=0;
for(int i=0;i<l;i++){
int w=s[i]-'a';
if(!son[x][w]){
son[x][w]=++tot;
f[tot]=x;
}
x=son[x][w];
}
return x;
}
inline void cal(int x){
sg[x]=0;
for(int i=0;i<26;i++)if(son[x][i])sg[x]^=sg[son[x][i]]+1;
}
void dfs(int x){
for(int i=0;i<26;i++)if(son[x][i])dfs(son[x][i]);
cal(x);
}
inline void up(int x){
while(x){
cal(x);
x=f[x];
}
cal(0);
}
int main(){
scanf("%d",&T);
for(C=1;C<=T;C++){
printf("Case %d:\n",C);
scanf("%d",&n);
while(n--)ins();
dfs(0);
scanf("%d",&n);
while(n--){
up(ins());
puts(sg[0]?"1":"2");
}
for(i=0;i<=tot;i++)for(j=f[i]=sg[i]=0;j<26;j++)son[i][j]=0;
tot=0;
}
}
G. Binary Strings
矩阵快速幂优化DP转移。
#include <bits/stdc++.h>
using namespace std ; typedef long long LL ;
const int mod=1e9+7;
void up(int &x,int y){x+=y;if(x>=mod)x-=mod;}
struct Mat{
int a[3][3];
Mat operator *(const Mat&x)const{
Mat ret;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
int t=0;
for(int k=0;k<3;k++){
up(t,1LL*a[i][k]*x.a[k][j]%mod);
}
ret.a[i][j]=t;
}
}
return ret;
}
void init(int t){
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
a[i][j]=i==j?t:0;
}
}
}
}ori;
Mat powmod(Mat x,LL y){
Mat ret;
ret.init(1);
while(y){
if(y&1){ret=ret*x;}
y>>=1;
x=x*x;
}
return ret;
}
int go(LL x){
Mat tmp=powmod(ori,x+1);
return tmp.a[0][2];
}
void solve(){
LL l,r,k;
scanf("%lld%lld%lld",&l,&r,&k);
ori.init(0);
ori.a[0][0]=1;
ori.a[0][1]=1;
ori.a[1][0]=1;
ori=powmod(ori,k);
ori.a[0][2]=1;
ori.a[1][2]=1;
ori.a[2][2]=1;
ori.a[2][0]=ori.a[2][1]=0;
int ans=go(r/k);
ans-=go((l-1)/k);
if(ans<0)ans+=mod;
printf("%d\n",ans);
}
int main () {
int _,cas=1;scanf("%d",&_);
while(_--){
printf("Case %d: ",cas++);
solve();
}
return 0 ;
}
H. Witcher Potion
$f[S][i][j][k]$表示已经使用过的药水集合为$S$,当前能量为$i$,毒性为$j$,上一次是否嗑药为$k$时最多能打多少只怪物,然后DP即可。
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
using namespace std;
typedef long long ll;
const int inf=10000000;
int T,K,M,n,i,j,k,ans,t,e[11],p[11],f[1<<8][111][111][2],o;
inline void up(int&x,int y){if(x<y)x=y;}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&K,&M,&n);
for(i=0;i<n;i++)scanf("%d",&e[i]);
for(i=0;i<n;i++)scanf("%d",&p[i]);
for(i=0;i<1<<n;i++)for(j=1;j<=100;j++)for(k=0;k<100;k++)f[i][j][k][0]=f[i][j][k][1]=-inf;
up(f[0][100][0][0],0);
for(i=0;i<1<<n;i++)for(j=100;j;j--)for(k=99;~k;k--)for(o=0;o<2;o++)if(f[i][j][k][o]>=0){
//kill a monster
if(j>K)up(f[i][j-K][max(0,k-M)][0],f[i][j][k][o]+1);
//drink
if(!o)for(t=0;t<n;t++)if(!(i>>t&1)){
if(k+p[t]<100)up(f[i|(1<<t)][min(100,j+e[t])][k+p[t]][1],f[i][j][k][o]);
} }
ans=0;
for(i=0;i<1<<n;i++)for(j=1;j<=100;j++)for(k=0;k<100;k++){
up(ans,f[i][j][k][0]);
up(ans,f[i][j][k][1]);
}
printf("%d\n",ans);
}
}
I. Sky Tax
根据根与询问点的位置关系分类讨论即可。
#include<cstdio>
#include<algorithm>
#include<cstdlib>
using namespace std;
typedef long long ll;
const int N=1000010,M=2000010;
int T,C,n,m,root,x,y,i,g[N],v[N<<1],nxt[N<<1],ed;
int st[N],en[N],size[N],dfn;
int son[N],top[N],d[N],f[N];
inline void add(int x,int y){
v[++ed]=y;nxt[ed]=g[x];g[x]=ed;
}
void dfs(int x){
size[x]=1;
for(int i=g[x];i;i=nxt[i])if(v[i]!=f[x]){
f[v[i]]=x,d[v[i]]=d[x]+1;
dfs(v[i]);
size[x]+=size[v[i]];
if(size[v[i]]>size[son[x]])son[x]=v[i];
}
}
void dfs2(int x,int y){
st[x]=++dfn;top[x]=y;
if(son[x])dfs2(son[x],y);
for(int i=g[x];i;i=nxt[i])if(v[i]!=son[x]&&v[i]!=f[x])dfs2(v[i],v[i]);
en[x]=dfn;
}
inline int lca2(int x,int y){
int t;
while(top[x]!=top[y])t=top[y],y=f[top[y]];
return x==y?t:son[x];
}
inline int ask(int x){
if(root==x)return n;
if(st[x]>st[root]||en[x]<en[root])return size[x];
return n-size[lca2(x,root)];
}
void check(int x){
if(x<1||x>n)exit(0);
}
int main(){
scanf("%d",&T);
for(C=1;C<=T;C++){
printf("Case #%d:\n",C);
scanf("%d%d%d",&n,&m,&root);
check(root);
for(ed=dfn=0,i=1;i<=n;i++)g[i]=0;
for(i=1;i<=n;i++)size[i]=son[i]=top[i]=f[i]=d[i]=0;
for(i=1;i<n;i++){
//x=i+1;y=rand()%i
scanf("%d%d",&x,&y);
check(x);
check(y);
add(x,y),add(y,x);
}
dfs(1);
dfs2(1,1);
while(m--){
scanf("%d%d",&x,&y);
check(y);
if(x==0)root=y;
else{
printf("%d\n",ask(y));
}
}
}
}
J. Printing Press
留坑。
K. Expected Number of Connected Components
留坑。
L. Coordinates
建树DFS即可确定出每个点的坐标。
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=100010,M=2000010;
const ll inf=1LL<<60;
int n,m,i,f[N],g[N],v[M],wx[M],wy[M],nxt[M],ed;
ll minx,miny,basex[N],basey[N],xx[N],yy[N];
inline void add(int x,int y,int dx,int dy){
v[++ed]=y;
wx[ed]=dx;
wy[ed]=dy;
nxt[ed]=g[x];
g[x]=ed;
}
void dfs(int x,int y,ll X,ll Y){
if(f[x])return;
f[x]=y;
xx[x]=X;
yy[x]=Y;
minx=min(minx,X);
miny=min(miny,Y);
for(int i=g[x];i;i=nxt[i])dfs(v[i],y,X+wx[i],Y+wy[i]);
}
int main(){
scanf("%d%d",&n,&m);
while(m--){
int x,y,dx,dy;
scanf("%d%d%d%d",&x,&y,&dx,&dy);
add(x,y,dx,dy);
add(y,x,-dx,-dy);
}
for(i=1;i<=n;i++)if(!f[i]){
minx=inf;
miny=inf;
dfs(i,i,0,0);
basex[i]=-minx;
basey[i]=-miny;
}
for(i=1;i<=n;i++)printf("%I64d %I64d\n",xx[i]+basex[f[i]],yy[i]+basey[f[i]]);
}
总结:
- I题发现模板有误。
2016-2017 ACM-ICPC Asia-Bangkok Regional Contest的更多相关文章
- 2017 ACM - ICPC Asia Ho Chi Minh City Regional Contest
2017 ACM - ICPC Asia Ho Chi Minh City Regional Contest A - Arranging Wine 题目描述:有\(R\)个红箱和\(W\)个白箱,将这 ...
- 2017 ACM/ICPC Asia Regional Shenyang Online spfa+最长路
transaction transaction transaction Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 132768/1 ...
- 2017 ACM ICPC Asia Regional - Daejeon
2017 ACM ICPC Asia Regional - Daejeon Problem A Broadcast Stations 题目描述:给出一棵树,每一个点有一个辐射距离\(p_i\)(待确定 ...
- 2017 ACM/ICPC Asia Regional Qingdao Online
Apple Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submi ...
- ACM ICPC Central Europe Regional Contest 2013 Jagiellonian University Kraków
ACM ICPC Central Europe Regional Contest 2013 Jagiellonian University Kraków Problem A: Rubik’s Rect ...
- 2019-2020 ICPC, Asia Jakarta Regional Contest (Online Mirror, ICPC Rules, Teams Preferred)
2019-2020 ICPC, Asia Jakarta Regional Contest (Online Mirror, ICPC Rules, Teams Preferred) easy: ACE ...
- HDU - 6215 2017 ACM/ICPC Asia Regional Qingdao Online J - Brute Force Sorting
Brute Force Sorting Time Limit: 1 Sec Memory Limit: 128 MB 题目连接 http://acm.hdu.edu.cn/showproblem.p ...
- 2017 ACM/ICPC Asia Regional Shenyang Online(部分题解)
HDU 6197 array array array 题意 输入n和k,表示输入n个整数和可以擦除的次数k,如果至多擦除k次能是的数组中的序列是不上升或者是不下降序列,就是魔力数组,否则不是. 解题思 ...
- 2017 ACM/ICPC Asia Regional Qingdao Online解题报告(部分)
HDU 6206 Apple 题意: 给出四个点的坐标(每个点的坐标值小于等于1,000,000,000,000),问最后一个点是否在前三个点组成的三角形的外接圆内,是输出Accept,否输出Reje ...
- HDU 6205(尺取法)2017 ACM/ICPC Asia Regional Shenyang Online
题目链接 emmmm...思路是群里群巨聊天讲这题是用尺取法.....emmm然后就没难度了,不过时间上3000多,有点.....盗了个低配本的读入挂发现就降到2800左右, 翻了下,发现神犇Clar ...
随机推荐
- webpack那些事儿
webpack那些事儿01-webpack到底是什么 webpack那些事儿02-从零开始 webpack那些事儿03-热插拔 hot webpack那些事儿04-spa项目实战分析 webpack那 ...
- git用法之[回滚代码]
我们在写代码的任何过程中,都有可能出错,任何过程都有可能要!回!滚!代!码!事关重大!一定要详细讲讲. 一.关于 工作区.暂存区.本地分支: 工作区:即自己当前分支所修改的代码,git add xx ...
- poi2015 bzoj4377-4386训练
就按时间顺序写吧 完成度:10/10 3.30 bzoj4385 首先一定是删去连续d个数,然后枚举终点,起点显然有单调性,用单调队列乱搞搞就可以啦 bzoj4378 首先才结论:可行当且仅当把所有大 ...
- touch事件中的touches、targetTouches和changedTouches详解
touches: 当前屏幕上所有触摸点的列表; targetTouches: 当前对象上所有触摸点的列表; changedTouches: 涉及当前(引发)事件的触摸点的列表 通过一个例子来区分一下触 ...
- 提交本地项目到github
要托管到github,那你就应该要有一个属于你自己的github帐号,所以你应该先到github.com注册 打开浏览器 在地址栏输入地址:github.com 填写用户名.邮箱.密码 点击Sign ...
- rpcbind服务说明及关闭
rpcbind服务说明及关闭 Posted by 破冰 on -- : Tuesday rpcbind服务停止命令 service portmap stop redhat 的rpc.statd服务: ...
- 2014 39th ACM-ICPC 北京赛区 总结
万万没想到,拿金了. 在经历了西安赛区的打铁经历,感觉我们已经很坦然了.怎么说呢,虽说有阴影,但那也是成长的一步.我在西安打铁之后跟队友跟姐姐说过“如果北京是铜或者铁,我就退役”.记得曾经,很多人问我 ...
- C+继承
// 继承.cpp : Defines the entry point for the console application.// #include "stdafx.h" str ...
- 如何在eclipse中通过Juit进行单元测试
1.什么是Junit Junit即单元测试,是JAVA语言的单元测试框架,是对程序的一个方法所进行的测试 一般都是由程序员自己通过Junit来进行测试,因此单元测试也叫程序员测试: 如果测试人员熟悉程 ...
- 使用Slf4j集成Log4j2构建项目日志系统的完美解决方案
一.背景 最近因为公司项目性能需要,我们考虑把以前基于的log4j的日志系统重构成基于Slf4j和log4j2的日志系统,因为,使用slf4j可以很好的保证我们的日志系统具有良好的兼容性,兼容当前常见 ...