A. Game with chocolates

因为差值必须是$P$的幂,故首先可以$O(\log n)$枚举出先手第一步所有取法,判断之后的游戏是否先手必败。

对于判断,首先特判非法的情况,并假设$n<m$,则题意可理解成将$n$或者$m$减小至$n-P^k$,在$P$进制下可以理解为$n$某一位减$1$,且这一位在减之前不能是$0$。

若是将$m$减小为$n-P^k$,则整个游戏都是确定的,回合数为$n$的数位之和,根据奇偶性即可判断胜负。

但若是将$n$减小为$m-P^k$,则要求$n$和$m$位数相同且最高位相等,这意味着进行这步操作后之后不能再进行这一步操作,先手可以利用这一步来使自己必胜。

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
ll P,n,m,k,a[99],b[99];
bool check(ll n,ll m){
if(n>m)swap(n,m);
ll k=m-n;
if(m/k%P==0)return 1;
while(k%P==0)k/=P;
if(k>1)return 1;
if(!n)return 0;
int la=0,lb=0;
while(n)a[++la]=n%P,n/=P;
while(m)b[++lb]=m%P,m/=P;
if(la==lb&&a[la]==b[lb])return 1;
for(int i=2;i<=la;i++)a[1]+=a[i];
return a[1]%2;
}
int main(){
scanf("%lld%lld%lld",&P,&n,&m);
for(k=1;k<=n;k*=P)if(n-k<m)if(!check(n,n-k)){
puts("YES");
printf("%lld %lld",n,n-k);
return 0;
}
for(k=1;k<=m;k*=P)if(m-k<n)if(!check(m-k,m)){
puts("YES");
printf("%lld %lld",m-k,m);
return 0;
}
puts("NO");
}

  

B. Birches

将相同的数合并,然后调和级数$O(n\log n)$枚举即可。

#include<cstdio>
const int N=111111;
int n,m,k,i,j,x,l,r,f[N];long long ans;
int main(){
scanf("%d%d",&n,&k);
while(n--){
scanf("%d",&x);
f[x]++;
}
n=100000;
for(i=1;i<=n;i++)if(f[i]&&k<i)
for(l=k;l<=n;l+=i)ans+=1LL*f[i]*f[l];
printf("%lld",ans);
}

  

C. Ancient CBS

按平方数分解构造。

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { }
#define MS(x, y) memset(x, y, sizeof(x))
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
const int N = 1e5 + 10, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
int casenum, casei;
int n;
char s[(int)3e5];
int h, t;
void solve(int w, int st)
{
for(int i = st; w >= i; ++i)
{
s[t++] = '(';
s[t++] = ')';
w -= i;
}
if(w == 0)return;
s[--h] = '(';
s[t++] = ')';
if(--w == 0)return;
solve(w, 2);
}
int main()
{
while(~scanf("%d", &n))
//for(int x = 1, n = 1e9 - x; x <= 1000000; ++x, --n)
{
h = t = 1e5; s[t] = 0;
solve(n, 1); s[t] = 0;
puts(s + h);
/*printf("%d\n", t - h);
if(t - h > 1e5)
{
puts("NO");
while(1);
}*/
}
return 0;
}
/*
【trick&&吐槽】 【题意】 【分析】 【时间复杂度&&优化】 */

  

D. Interactive lock

爆搜得出方案即可。

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { }
#define MS(x, y) memset(x, y, sizeof(x))
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
const int N = 1e5 + 10, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
int casenum, casei;
int n;
int a[100] = {0,
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 22, 24, 14, 18, 16, 17, 19, 20, 21, 23, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 78, 44, 45, 46, 47, 48, 49, 50, 51, 100, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 98, 92, 97, 99, 96};
int top = 96; /*
bool e[N];
int p[N];
int v[N];
void prime()
{
int g = 0;
int k = 0;
for(int i = 2; i <= 10000; ++i)
{
if(!e[i])
{
p[++g] = i;
for(int j = i + i; j <= 10000; j += i)
{
e[j] = 1;
}
}
else
{
v[++k] = i;
}
}
}
*/ set<int>can;
bool dfs(int g, vector<int>rst)
{
if(rst.size() == 0)
{
puts("bingo");
printf("%d\n", g - 1);
for(int i = 1; i < g; ++i)printf("%d, ", a[i]); puts("");
return 1;
}
set<int>::iterator it, nit;
for(it = can.begin(); it != can.end(); it = nit)
{
if(*it > rst.front())return 0;
vector<int>nxt;
for(auto x : rst)if(x % *it)
{
nxt.push_back(x - *it);
}
a[g] = *it;
nit = it; ++nit;
can.erase(a[g]);
if(dfs(g + 1, nxt))return 1;
can.insert(a[g]);
} /*for(auto it : can)
{
if(it > rst.front())return 0;
vector<int>nxt;
for(auto x : rst)if(x % it)
{
nxt.push_back(x - it);
}
a[g] = it;
can.erase(a[g]);
if(dfs(g + 1, nxt))return 1;
can.insert(a[g]);
}*/
return 0;
} void solve()
{
for(int i = 2; i <= 100; ++i)can.insert(i);
vector<int>rst;
for(int i = 100; i <= 10000; ++i)rst.push_back(i);
dfs(1, rst);
} bool guess(int x)
{
for(int i = 1; i <= top; ++i)
{
if(a[i] > x)
{
printf("%d\n", x);
return 0;
}
if(x % a[i] == 0)return 1;
x -= a[i];
}
return 0;
} int main()
{
//prime();
//solve();
int T; scanf("%d", &T);
while(T--)
{
for(int i = 1; i <= top; ++i)
{
printf("%d\n", a[i]); fflush(stdout);
char s[10]; scanf("%s", s);
if(s[0] == 'Y')break;
}
} /*
for(int i = 100; i <= 10000; ++i)
{
if(!guess(i))
{
printf("%d\n", i);
}
}
puts("haha");
*/ return 0;
}
/*
【trick&&吐槽】 【题意】 【分析】 【时间复杂度&&优化】 */

  

E. Interval divisibility

对于每个约数计算贡献,分段求和即可。

时间复杂度$O(\sqrt{n})$。

#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
const ll P=1000000007,inv2=(P+1)/2;
ll f(ll n){
n%=P;
return n*(n+1)%P*inv2%P;
}
ll cal(ll n){
ll ret=0;
for(ll i=1;i<=n;){
ll j=n/(n/i);
ret+=f(n/i)*((i+j)%P)%P*((j-i+1)%P)%P*inv2%P;
ret%=P;
i=j+1;
}
return ret;
}
int main(){
ll l,r;
cin>>l>>r;
ll ans=cal(r)-cal(l-1);
ans=ans%P;
ans=ans+P;
ans%=P;
cout<<ans;
}

  

F. A trick

分类讨论。

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { }
#define MS(x, y) memset(x, y, sizeof(x))
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
const int N = 1e5 + 10, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
int casenum, casei;
int n;
int main()
{
while(~scanf("%d", &n))
{
if(n == 0)
{
puts("-1");
continue;
}
int x = n;
int sum = 0;
while(x)
{
sum += x % 10;
x /= 10;
}
if(sum == 9 * 9)
{
puts("-1");
}
else
{
int tmp1 = sum;
int v1 = 0;
while(tmp1)
{
int can = min(tmp1, 9);
tmp1 -= can;
v1 = v1 * 10 + can;
} int tmp2 = sum;
int v2 = 0;
bool flag = 1;
while(tmp2)
{
int can = min(tmp2, 9 - flag);
flag = 0;
tmp2 -= can;
v2 = v2 * 10 + can;
}
if(v1 != n)printf("%d\n", v1);
else if(v2 != n)printf("%d\n", v2);
else printf("%d0\n", v1);
}
}
return 0;
}
/*
【trick&&吐槽】 【题意】 【分析】 【时间复杂度&&优化】 */

  

G. Highest ratings year

首先求出所有路径长度之和,并直接除以$2$,那么奇数长度的路径会算错,故再算出奇数长度的路径数即可。

时间复杂度$O(n)$。

#include<cstdio>
typedef long long ll;
const int N=100010;
int n,i,x,y,g[N],v[N<<1],nxt[N<<1],ed;
int cnt[2],d[N],size[N];
ll ans;
inline void add(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
void dfs(int x,int y){
d[x]=d[y]^1;
cnt[d[x]]++;
size[x]=1;
for(int i=g[x];i;i=nxt[i])if(v[i]!=y){
dfs(v[i],x);
size[x]+=size[v[i]];
ans+=1LL*size[v[i]]*(n-size[v[i]]);
}
}
int main(){
scanf("%d",&n);
for(i=1;i<n;i++)scanf("%d%d",&x,&y),add(x,y),add(y,x);
dfs(1,0);
ll odd=1LL*cnt[0]*cnt[1];
ans/=2;
ans+=odd-odd/2;
printf("%lld",ans);
}

  

H. Spells

设$f[i][j]$表示考虑$S$前$i$个位置,被一路交换过来的字符是$j$能匹配成功的字符串个数,当且仅当$j$和当前字符不相同时才进行转移。

那么转移可以写成矩阵的形式,快速幂计算。

对于矩阵的构造,注意到每次单个字符的转移矩阵与$E$相比只有常数个位置不同,故可以利用这点在$O(26)$时间内计算矩阵乘法。

时间复杂度$O(26\sum|S|+n26^3\log k)$。

#include<cstdio>
#include<cstring>
#define rep(i) for(int i=0;i<N;i++)
const int N=28,P=1000000007;
int n,m,K,f[N],g[N][N];char s[10010];
inline void mul(){
static int h[N][N];
rep(i)rep(j)h[i][j]=0;
rep(i)rep(j)if(g[i][j])rep(k)if(g[j][k])h[i][k]=(1LL*g[i][j]*g[j][k]+h[i][k])%P;
rep(i)rep(j)g[i][j]=h[i][j];
}
inline void apply(){
static int h[N];
rep(i){
h[i]=0;
rep(j)h[i]=(1LL*g[i][j]*f[j]+h[i])%P;
}
rep(i)f[i]=h[i];
}
inline void gao(int x){//2..27
//w[x][0]=1
//w[x][x]=P-1
//w[0][1]=1
//w[0][x]=P-1
//w[1][x]=P-1
//w[1][0]=1
static int h[N][N];
rep(i){
h[0][i]=g[0][i];
h[1][i]=g[1][i];
h[x][i]=g[x][i];
}
rep(i){
g[x][i]=(h[0][i]+g[x][i])%P;
g[x][i]=(1LL*(P-1)*h[x][i]+g[x][i])%P;
g[0][i]=(h[1][i]+g[0][i])%P;
g[0][i]=(1LL*(P-1)*h[x][i]+g[0][i])%P;
g[1][i]=(1LL*(P-1)*h[x][i]+g[1][i])%P;
g[1][i]=(h[0][i]+g[1][i])%P;
}
}
int main(){
scanf("%d",&n);
f[0]=1;
//1:sum = 2+...+27
while(n--){
scanf("%s%d",s,&K);
m=strlen(s);
rep(i)rep(j)g[i][j]=i==j;
for(int i=0;i<m;i++)gao(s[i]-'a'+2);
for(;K;K>>=1,mul())if(K&1)apply();
}
printf("%d",f[0]);
}
/*
7
a 1
n 1
g 1
n 1
g 1
a 1
n 1 6
a 1
n 1
g 1
n 1
g 1
an 1
*/

  

I. Silver table

$n$的方案为将$n-1$的方案复制后放在上下左右四个地方,并将右上块和左下块全体加$2^k-1$,再将左下块反对角线全体加$2^k-1$得到。

#include<cstdio>
const int N=3222;
int i,j,k,n,f[N][N];
int main(){
f[1][1]=1;
for(i=2;i<=11;i++){
int len=1<<(i-1);
int hal=len/2;
for(j=1;j<=hal;j++)for(k=1;k<=hal;k++){
f[j+hal][k+hal]=f[j][k];
f[j+hal][k]=f[j][k+hal]=f[j][k]+len-1;
}
for(j=1;j<=hal;j++)f[j+hal][j]+=len-1;
}
scanf("%d",&n);
n=1<<n;
for(i=1;i<=n;i++){
for(j=1;j<=n;j++)printf("%d ",f[i][j]);
puts("");
}
}

  

J. Soldier’s life

问题等价于找两条间距最小的平行线夹住所有点,故求出凸包后枚举每条边求出最远点即可。

#include<cstdio>
#include<algorithm>
#include<set>
#include<cmath>
using namespace std;
typedef double DB;
const int N=10000;
const DB eps = 1e-9, pi = acos(-1.0);
DB ans=1e100;
int n,m,i;
struct PT{
DB x, y;
PT(DB x = 0, DB y = 0):x(x), y(y){}
void input(){scanf("%lf%lf", &x, &y);}
PT operator-(const PT&p)const{return PT(x-p.x,y-p.y);}
PT operator+(const PT&p)const{return PT(x+p.x,y+p.y);}
PT operator*(double p)const{return PT(x*p,y*p);}
PT operator/(double p)const{return PT(x/p,y/p);}
bool operator < (const PT &p) const{
if(fabs(x - p.x) > eps) return x < p.x; return y < p.y;}
void output(){printf("%.15f %.15f\n", x, y);}
DB len()const{return hypot(x,y);}
PT rot90()const{return PT(-y,x);}
PT trunc(double l)const{return (*this)*l/len();}
}a[N],b[N],c[N],fina,finb,f[N],fin[N];
DB lim=1e100;
DB cross(const PT&a,const PT&b){return a.x*b.y-a.y*b.x;}
DB vect(PT p, PT p1, PT p2){
return (p1.x - p.x) * (p2.y - p.y) - (p1.y - p.y) * (p2.x - p.x);
}
int convex_hull(PT *p, int n, PT *q){
int i, k, m; sort(p, p + n); m = 0;
for(i = 0; i < n; q[m++] = p[i++])
while(m > 1 && vect(q[m - 2], q[m - 1], p[i]) < eps) m --;
k = m;
for(i = n - 2; i >= 0; q[m ++] = p[i --])
while(m > k && vect(q[m - 2], q[m - 1], p[i]) < eps) m --;
return --m;
}
void solve(PT A,PT B){
DB mx=0;
for(int i=0;i<n;i++)mx=max(mx,fabs(cross(a[i]-A,B-A)));
mx/=(B-A).len();
mx/=2;
if(mx<ans){
ans=mx;
fina=A;
finb=B;
}
}
PT line_intersection(PT a,PT b,PT p,PT q){
double U=cross(p-a,q-p),D=cross(b-a,q-p);
return a+(b-a)*(U/D);
}
void gao(PT A,PT B){
PT fa=A-B;
fa=fa.rot90();
DB ret=0;
for(int i=0;i<n;i++){
PT C=a[i],D=C+fa;
PT now=line_intersection(A,B,C,D);
DB dis=(now-C).len();
ret=max(ret,dis);
f[i]=now;
}
if(ret<lim){
lim=ret;
for(int i=0;i<n;i++)fin[i]=f[i];
}
}
int main(){
scanf("%d",&n);
for(i=0;i<n;i++)a[i].input(),b[i]=a[i];
m=convex_hull(b,n,c);
for(i=0;i<m;i++)solve(c[i],c[(i+1)%m]);
PT tmp=finb-fina;
tmp=tmp.rot90();
tmp=tmp.trunc(ans);
gao(fina+tmp,finb+tmp);
gao(fina-tmp,finb-tmp);
printf("%.10f\n",lim);
for(i=0;i<n;i++)fin[i].output();
}

  

K. Casino

DP,$f[n][m]$表示还剩$n$张红卡,$m$张黑卡的最大期望收益。

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=111;
int n,m;double f[N][N];bool v[N][N];
double dfs(int n,int m){
if(!n&&!m)return 0;
if(v[n][m])return f[n][m];
v[n][m]=1;
double ret=0;
if(n)ret+=(dfs(n-1,m)+1)*n;
if(m)ret+=(dfs(n,m-1)-1)*m;
return f[n][m]=max(ret/(n+m),0.0);
}
int main(){
scanf("%d%d",&n,&m);
printf("%.15f",dfs(n,m));
}

  

BSUIR Open Finals的更多相关文章

  1. HDU-AcmKeHaoWanLe训练实录

    菜鸡队训练实录. 现场赛记录:[名称:奖项/排名] 2017: ICPC Shenyang:Gold/3 CCPC Hangzhou:Gold/3 ICPC Beijing:Gold/13 CCPC ...

  2. Lesnoe Ozero 2016. BSUIR Open 2016 Finals

    A. Street magic 数位DP,设$f[i][j][k]$表示从低到高考虑$x$的后$i$位,$x$和$m$大小关系为$j$,和$n$大小关系为$k$的方案数. #include<cs ...

  3. ACM - ICPC World Finals 2013 F Low Power

    原题下载:http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf 题目翻译: 问题描述 有n个机器,每个机器有2个芯片,每个 ...

  4. Codeforces Round #342 (Div. 2) D. Finals in arithmetic 贪心

    D. Finals in arithmetic 题目连接: http://www.codeforces.com/contest/625/problem/D Description Vitya is s ...

  5. ACM - ICPC World Finals 2013 C Surely You Congest

    原题下载:http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf 题目翻译: 试题来源 ACM/ICPC World Fin ...

  6. ACM - ICPC World Finals 2013 A Self-Assembly

    原题下载 : http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf 这道题其实是2013年我AC的第一道题,非常的开心,这 ...

  7. [ahu 1248] NBA Finals

    NBA Finals Time Limit: 1000 ms   Case Time Limit: 1000 ms   Memory Limit: 64 MBTotal Submission: 251 ...

  8. [Swust OJ 649]--NBA Finals(dp,后台略(hen)坑)

    题目链接:http://acm.swust.edu.cn/problem/649/ Time limit(ms): 1000 Memory limit(kb): 65535 Consider two ...

  9. Codeforces Round #403 (Div. 2, based on Technocup 2017 Finals)

    Codeforces Round #403 (Div. 2, based on Technocup 2017 Finals) 说一点东西: 昨天晚上$9:05$开始太不好了,我在学校学校$9:40$放 ...

随机推荐

  1. mycat 使用

    介绍 支持SQL92标准 支持MySQL.Oracle.DB2.SQL Server.PostgreSQL等DB的常见SQL语法 遵守Mysql原生协议,跨语言,跨平台,跨数据库的通用中间件代理. 基 ...

  2. Java进程线程笔记

    什么是并行和并发? 并发和并行是即相似又有区别:(微观) 并行:指两个或多个事件在同一时刻发生: 强调的是时间点. 并发:指两个或多个事件在同一时间段内发生: 强调的是时间段. 进程和线程的区别? 进 ...

  3. Fiddler状态栏

    Fiddler状态栏显示了Fiddler的一些配置信息,我们也可以点击这些配置信息进行快速配置. 以下图为例: 状态栏一共显示了四项信息:1.Capturing/空:2.过滤进程类型:3.Web Se ...

  4. [再寄小读者之数学篇](2014-06-23 二阶导数估计 [中国科学技术大学2013年高等数学B 考研试题])

    设 $f(x)$ 二阶连续可导, $f(0)=f(1)=0$, $\dps{\max_{0\leq x\leq 1}f(x)=2}$. 证明: $$\bex \min_{0\leq x\leq 1}f ...

  5. INI配置文件的格式

    为什么要用INI文件?如果我们程序没有任何配置文件时,这样的程序对外是全封闭的,一旦程序需要修改一些参数必须要修改程序代码本身并重新编译,这样很不好,所以要用配置文件,让程序出厂后还能根据需要进行必要 ...

  6. Python“函数式编程”中常用的函数

    1.map(func,seq[,seq,...]) 对序列中的每个元素应用函数,python2中map()返回的是列表,python3中返回的是迭代器,可以用list()转换成列表.以下例子为pyth ...

  7. 20165237 2017-2018-2《Java程序设计》课程总结

    20165237 2017-2018-2<Java程序设计>课程总结 每周作业链接汇总 我期望的师生关系 学习基础和C语言基础调查 Linux安装及学习 第一周学习总结 第二周学习总结 第 ...

  8. (一)Java工程化--Maven基础

    Maven 读作['mevən] 翻译成中文是"内行,专家" Maven是什么 包依赖的前世今生: 原始的jar包引用--> ant --> maven. 是一种项目管 ...

  9. 基于redis的cas集群配置

    1.cas ticket统一存储 做cas集群首先需要将ticket拿出来,做统一存储,以便每个节点访问到的数据一致.官方提供基于memcached的方案,由于项目需要,需要做计入redis,根据官方 ...

  10. [转] fastText

    mark- from : https://www.jiqizhixin.com/articles/2018-06-05-3 fastText的起源 fastText是FAIR(Facebook AIR ...