# Lesnoe Ozero 2016. BSUIR Open 2016 Finals

A. Street magic

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=80,P=1000000007;
char a[N],b[N];
int n,m,i,j,k,x,lim,f[N][2][2];
/*
0:=m
1:>m

0:<=n
1:>n
*/
inline void up(int&a,int b){a=a+b<P?a+b:a+b-P;}
int main(){
scanf("%s%s",a+1,b+1);
n=strlen(a+1);
m=strlen(b+1);
reverse(a+1,a+n+1);
reverse(b+1,b+m+1);
lim=max(n,m)+1;
a[0]=b[0]=0;
for(i=1;i<=n;i++)a[i]-='0';
for(i=n+1;i<=lim;i++)a[i]=0;
for(i=1;i<=m;i++)b[i]-='0';
for(i=m+1;i<=lim;i++)b[i]=0;

f[0][0][0]=1;
for(i=0;i<lim;i++)for(j=0;j<2;j++)for(k=0;k<2;k++)if(f[i][j][k]){
for(x=0;x<10;x++){
int nj,nk;
if(x<b[i+1])continue;
if(x==b[i+1]){
nj=j;
}else nj=1;
if(x==a[i+1]){
nk=k;
}else{
if(x>a[i+1])nk=1;
else nk=0;
}
up(f[i+1][nj][nk],f[i][j][k]);
}
}

printf("%d",(f[lim][0][0]+f[lim][1][0])%P);
}


B. Variety

#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<vector>
using namespace std;
const int N=1010;
int o;
int root,r,c,n,i,j,initroot;
int flag;
int mx;
int cnt;
long long ans;
struct P{int x,y;P(){}P(int _x,int _y){x=_x,y=_y;}}x,y;
struct E{int c,x,y;E(){}E(int _c,int _x,int _y){c=_c,x=_x,y=_y;}}a[1000010];
inline bool cmp(const E&a,const E&b){return a.c==b.c?a.x<b.x:a.c<b.c;}
namespace Treap{
const int M=20000010;
int h[N],l[N],r[N],size[N],tag[N],sum[N];
int q[M][2];
char w[M];
int top;
inline void push(int x,int y,int z){
if(flag)return;
top++;
if(top>mx)mx=top;
w[top]=x;
q[top][0]=y;
q[top][1]=z;
}
inline void rec(){
int x=w[top],y=q[top][0],z=q[top][1];
top--;
if(x==0)h[y]=z;
if(x==1)l[y]=z;
if(x==2)r[y]=z;
if(x==3)size[y]=z;
if(x==4)tag[y]=z;
if(x==5)sum[y]=z;
}
inline void up(int x){
push(3,x,size[x]);
push(5,x,sum[x]);
size[x]=size[l[x]]+size[r[x]]+1;
sum[x]=sum[l[x]]+sum[r[x]]+((h[l[x]]-h[x])*size[l[x]]*(size[l[x]]+1)>>1)+((h[r[x]]-h[x])*size[r[x]]*(size[r[x]]+1)>>1);
}
if(!x)return;
push(0,x,h[x]);
push(4,x,tag[x]);
h[x]+=p;tag[x]+=p;
}
inline void pb(int x){
if(tag[x]){
push(4,x,tag[x]);
tag[x]=0;
}
}
P split(int x,int y){
if(!x)return P(0,0);
pb(x);
if(size[l[x]]+1<=y){
P t=split(r[x],y-size[l[x]]-1);
push(2,x,r[x]);
return r[x]=t.x,up(x),P(x,t.y);
}
P t=split(l[x],y);
push(1,x,l[x]);
return l[x]=t.y,up(x),P(t.x,x);
}
int merge(int x,int y){
if(!x)return y;
if(!y)return x;
pb(x),pb(y);
if(h[x]<h[y]){
int z=merge(r[x],y);
push(2,x,r[z]);
return r[x]=z,up(x),x;
}
int z=merge(x,l[y]);
push(1,y,l[y]);
return l[y]=z,up(y),y;
}
int build(int a,int b){
if(a>b)return 0;
int mid=(a+b)>>1;
l[mid]=build(a,mid-1);
r[mid]=build(mid+1,b);
up(mid);
return mid;
}
}
inline void go(int k){
if(k<=0)return;
ans-=1LL*Treap::sum[root]*k;
long long tmp=1LL*Treap::size[root]*(Treap::size[root]+1)/2;
long long st=Treap::h[root];
ans-=1LL*(st*2+k+1)*k/2*tmp;
}
inline void init(){
flag=1;
Treap::top=0;
for(root=i=0;i<=c;i++)Treap::h[i]=Treap::l[i]=Treap::r[i]=Treap::size[i]=Treap::tag[i]=Treap::sum[i]=0;
/*
root=r;Treap::up(r);
for(i=r-1;i;i--){
Treap::r[i]=i+1;
Treap::up(i);
}*/
//root=1;
root=Treap::build(1,r);
flag=0;
initroot=root;
}
inline void solve(int L,int R){
int i,j,k;
ans+=1LL*r*(r+1)*c*(c+1)>>2;
flag=(R-L)>r;
int pre=0;
for(i=L;i<=R;i=j){
for(j=i;j<=R&&a[i].x==a[j].x;j++);
go(a[i].x-pre-1);
pre=a[i].x;
for(k=i;k<j;k++){
x=Treap::split(root,a[k].y-1),y=Treap::split(x.y,1);
Treap::push(0,y.x,Treap::h[y.x]);
Treap::h[y.x]=0;
root=Treap::merge(Treap::merge(x.x,y.x),y.y);
}
ans-=Treap::sum[root]+((1LL*Treap::h[root]*Treap::size[root]*(Treap::size[root]+1))>>1);
}
go(r-pre);
if(flag)init();
else{
root=initroot;
while(Treap::top)Treap::rec();
}
}
int main(){
scanf("%d",&r);c=r;
for(i=1;i<=r;i++)for(j=1;j<=c;j++){
scanf("%d",&o);
//o=rand()%(r*c)+1;
a[++n]=E(o,i,j);
}
std::sort(a+1,a+n+1,cmp);
if(a[1].c==a[n].c)return puts("1"),0;
ans=0;
init();
for(i=1;i<=n;i=j){
for(j=i;j<=n&&a[i].c==a[j].c;j++);
solve(i,j-1);
}
long long all=1LL*r*(r+1)*c*(c+1)/4;
double fin=1.0*ans/all;
printf("%.15f",fin);
}


C. Crime fiction society

#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 = 1e7 + 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[N], vis[N], nxt[N];
//
int tot,i,j,p[N/8],v[N];
inline int divide(int n){
int ans = 1e9;
while(n>1){
int x=v[n];
n/=x;
while(vis[nxt[x]])
{
nxt[x] += x;
/*if(nxt[x] > 1e7)
{
puts("NO");
while(1);
}*/
}
ans = min(ans, nxt[x]);
}
return ans;
}
void init(){
vis[0] = 1;
int top = 1e7;
for(i=2;i<=top;i++){
if(!v[i])v[p[tot++]=i]=i;
for(j=0;j<tot&&1LL*i*p[j]<=top;j++){
v[i*p[j]]=p[j];
if(i%p[j]==0)break;
}
}
}
//
void table()
{
int top = 3e6;
a[1] = 1; vis[1] = 1;
a[2] = 2; vis[2] = 1;
for(int i = 3; i <= top; ++i)
{
a[i] = divide(a[i - 1]);
vis[a[i]] = 1;
//printf("%d %d\n", i, a[i]);
}
//puts("finish");
}
int main()
{
init();
table();
scanf("%d", &n);
printf("%d\n", a[n]);
return 0;
}
/*
【trick&&吐槽】

【题意】

【分析】

【时间复杂度&&优化】

*/


D. Brand registration

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1010;
const double pi2=acos(-1.0)*2.0,pi=acos(-1.0)/2.0,eps=1e-8;
int n,m,i,j,k,q[N*2];ll f[N][N],g[N][N],ans;
double b[N],c[N*2];
ll s[N*2];
struct P{
int x,y;
}a[N];
inline bool cmp(int x,int y){
return b[x]<b[y];
}
void dpleft(){
for(i=1;i<=n;i++)for(j=1;j<=n;j++)g[i][j]=0;
for(i=1;i<=n;i++){
m=0;
for(j=1;j<=n;j++)if(i!=j){
b[j]=atan2(a[j].y-a[i].y,a[j].x-a[i].x);
q[++m]=j;
}
sort(q+1,q+m+1,cmp);//counter clock wise
for(j=1;j<=m;j++){
c[j]=b[q[j]];
c[j+m]=c[j]+pi2;
q[j+m]=q[j];
}
for(j=1;j<=m*2;j++)s[j]=s[j-1]+f[q[j]][i];
for(j=m,k=m*2;j;j--){
k=min(k,j+m-1);
while(k>j&&c[k]-c[j]+eps>pi)k--;
g[i][q[j]]+=s[k]-s[j];
}
}
for(i=1;i<=n;i++)for(j=1;j<=n;j++)f[i][j]=g[i][j];
}
void dpright(){
for(i=1;i<=n;i++)for(j=1;j<=n;j++)g[i][j]=0;
for(i=1;i<=n;i++){
m=0;
for(j=1;j<=n;j++)if(i!=j){
b[j]=atan2(a[j].y-a[i].y,a[j].x-a[i].x);
q[++m]=j;
}
sort(q+1,q+m+1,cmp);//counter clock wise
for(j=1;j<=m;j++){
c[j]=b[q[j]];
c[j+m]=c[j]+pi2;
q[j+m]=q[j];
}
for(j=1;j<=m*2;j++)s[j]=s[j-1]+f[q[j]][i];
for(j=m+1,k=1;j<=m*2;j++){
k=max(k,j-m+1);
while(k<j&&c[j]-c[k]+eps>pi)k++;
g[i][q[j]]+=s[j-1]-s[k-1];
}
}
for(i=1;i<=n;i++)for(j=1;j<=n;j++)f[i][j]=g[i][j];
}
int main(){
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y);
for(i=1;i<=n;i++)for(j=1;j<=n;j++)if(i!=j)f[i][j]=1;
dpleft();
dpright();
dpleft();
dpright();
for(i=1;i<=n;i++)for(j=1;j<=n;j++)if(i!=j)ans+=f[i][j];
printf("%lld",ans/2);
}


E. Elections

#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;
const int INF = 1e9;
int f[N];
int a[N];
int m;

int main()
{
while(~ scanf("%d", &n)){
m = 0;
for(int i = 1; i * i <= n; i ++){
if(n % i == 0){
a[++ m] = i;
if(i * i != n) a[++ m] = n / i;
}
}
sort(a + 1, a + m + 1);
for(int i = 1; i <= m; i ++) f[i] = INF;

for(int i = 1; i <= m; i ++){
f[i] = a[i] / 2 + 1;
for(int j = 1; j < i; j ++){
if(a[i] % a[j] == 0){	// 每份个数
f[i] = min(f[i], f[j] * (a[i] / a[j] / 2 + 1));
}
}
}
printf("%d\n", f[m]);
}
return 0;
}
/*
【trick&&吐槽】

【题意】

【分析】

【时间复杂度&&优化】

*/


F. Cactus

#include<cstdio>
#define rep(i) for(int i=0;i<3;i++)
#define FOR(i) for(int i=0;i<2;i++)
const int N=100010,M=200010,P=1000000007;
int n,m,i,x,y,g[N],v[M<<1],nxt[M<<1],ed;
int vis[N],dfn,fa[N];
int isbot[N],istop[N],in[N];
int f[N][3][3][2];
int dp[3][3][2],tmp[3][3][2];//connect with down?
int ans;
inline void up(int&a,int b){a=a+b<P?a+b:a+b-P;}
inline void clr(){
rep(i)rep(j)FOR(k)tmp[i][j][k]=0;
}
inline void go(){
rep(i)rep(j)FOR(k)dp[i][j][k]=tmp[i][j][k];
}
void dfs(int x,int y){
fa[x]=y;
vis[x]=++dfn;
//printf("fa[%d]=%d\n",x,y);
for(int i=g[x];i;i=nxt[i]){
int u=v[i];
if(u==y)continue;
if(!vis[u]){
dfs(u,x);
}else if(vis[u]<vis[x]){
int j=x;
isbot[x]=1;
while(j!=u){
if(fa[j]==u)istop[j]=1;
in[j]=1;
j=fa[j];
}
}
}
clr();
go();
dp[0][0][0]=1;
for(int i=g[x];i;i=nxt[i]){
int u=v[i];
if(fa[u]!=x)continue;
clr();
if(istop[u]){
rep(A)rep(B)FOR(k)if(dp[A][B][k])rep(C)rep(D)FOR(l)if(f[u][C][D][l]){
int w=1LL*dp[A][B][k]*f[u][C][D][l]%P;
//not choose (x,u) not choose ex
up(tmp[A][B][k],w);
//not choose (x,u) choose ex
if(A+D+1<3){
//if(A+D+1==2&&x==1)printf("! %d %d %d %d %d\n",A,B,C,D,w);
//if(x!=1)
//if(x==1)printf("! %d %d %d %d %d\n",A,B,C,D,w);
up(tmp[A+D+1][B][k],w);
}
//choose(x,u) not choose ex
if(A+C+1<3)up(tmp[A+C+1][B][k],w);
//choose(x,u) choose ex
if(A+C+D+2<3){
//if(x==1)printf("! %d %d %d %d %d\n",A,B,C,D,w);
up(tmp[A+C+D+2][B][k],w);
}
}
}else if(in[u]){//same circle
rep(A)rep(B)FOR(k)if(dp[A][B][k])rep(C)rep(D)FOR(l)if(f[u][C][D][l]){
int w=1LL*dp[A][B][k]*f[u][C][D][l]%P;
//not choose(x,u)
up(tmp[A][D][0],w);
//choose(x,u)
if(A+C+1<3){
up(tmp[A+C+1][D][l],w);
}
}
}else{
rep(A)rep(B)FOR(k)if(dp[A][B][k])rep(C)rep(D)FOR(l)if(f[u][C][D][l]){
int w=1LL*dp[A][B][k]*f[u][C][D][l]%P;
//not choose(x,u)
up(tmp[A][B][k],w);
//choose(x,u)
if(A+C+1<3)up(tmp[A+C+1][B][k],w);
}
}
go();
}
clr();
rep(A)rep(B)FOR(k)if(dp[A][B][k])up(tmp[A][k?A:B][k],dp[A][B][k]);
go();
if(isbot[x])rep(i)f[x][i][i][1]=dp[i][0][0];
else rep(i)rep(j)FOR(k)f[x][i][j][k]=dp[i][j][k];
//rep(i)rep(j)if(f[x][i][j])printf("f[%d][%d][%d]=%d\n",x,i,j,f[x][i][j]);
}
int main(){
scanf("%d%d",&n,&m);
for(ed=i=1;i<=m;i++){
scanf("%d%d",&x,&y);
}
dfs(1,0);
rep(i)FOR(j)up(ans,f[1][i][0][j]);
printf("%d",ans);
}
/*
5 5
1 2
3 4
5 4
3 2
3 1

4 4
1 2
1 3
2 3
3 4
*/


G. Hard exam

#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 = 1e7 + 10, M = 0, inf = 0x3f3f3f3f;
int casenum, casei;

int n, t;
set<int> sot;
set<int> :: iterator it;
int q0, a, b, m, k;
const int top = 3e3;
int c[N];

int main()
{
while(~ scanf("%d%d", &n, &t)){
scanf("%d%d%d%d", &q0, &a, &b, &m);
LL Z = 1LL * n * n + 1;
if(n >= top){
int ans = 0;
for(int i = 1; i <= t; i ++){
q0 = (1LL * q0 * a + b) % m;
k = q0 % Z;
for(int j = 0; j <= n; j ++){
LL x = 1LL * k - 1LL * n * n + 1LL * j * n;
LL y = 2LL * j - n;
if(y && x % y == 0 && x / y <= n && x / y >= 0 || x == 0 && y == 0) {ans ++; break;}
}
}
printf("%d\n", ans);
}
else{
int siz = 0;
for(int i = 0; i <= n; i ++){
for(int j = i; j <= n; j ++){
c[++ siz] = 1LL * n * n + 2 * i * j - (i + j) * n;
}
}
sort(c + 1, c + siz + 1);
int ans = 0;
for(int i = 1; i <= t; i ++){
q0 = (1LL * q0 * a + b) % m;
k = q0 % Z;
if(*lower_bound(c + 1, c + siz + 1, k) == k) ans ++;
}
printf("%d\n", ans);
}
}
return 0;
}
/*
【trick&&吐槽】

5 6
9 1 2 999999993

85 155
88 120 53 980090303

【题意】

【分析】

【时间复杂度&&优化】

*/


H. A$+$B

$\lfloor\frac{s}{2}\rfloor$与$s-\lfloor\frac{s}{2}\rfloor$是一组合法解。

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
ll s,m;
int main(){
scanf("%lld",&s);
m=s/2;
printf("%lld %lld",m,s-m);
}


I. Credit history

DP求出$f$和$g$后每次按照最优转移行动即可。

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll inf=1LL<<60;
int me,n,m,i,j,k;
ll p[100],w[100];
ll f[1<<18],g[1<<18][10];
bool vf[1<<18],vg[1<<18][18];
ll calf(int S);
ll calg(int S,int o){
if(vg[S][o])return g[S][o];
vg[S][o]=1;
ll ret=inf;
for(int i=0;i<m;i++)if(S>>i&1)ret=min(ret,calf(S^(1<<i))+o*w[i]);
return g[S][o]=ret;
}
ll calf(int S){
if(!S)return 0;
if(vf[S])return f[S];
vf[S]=1;
ll ret=-inf;
for(int i=0;i<10;i++)ret=max(ret,calg(S,i));
return f[S]=ret;
}
int getpos(int x,int y){
y=n-y;
if(x==1)return y;
return y+n;
}
void write(int S){
printf("%d %d\n",S/n+1,n-S%n);
fflush(stdout);
}
int main(){
scanf("%d%d",&me,&n);
for(p[0]=i=1;i<=n;i++)p[i]=p[i-1]*10;
for(i=0;i<n;i++)w[m++]=p[i];
for(i=0;i<n;i++)w[m++]=-p[i];
//for(i=0;i<m;i++)printf("%lld\n",w[i]);
int S=(1<<m)-1;
for(int round=n*2;round--;){
if(me==1){//bank
ll ret=-inf;
for(i=0;i<10;i++)ret=max(ret,calg(S,i));
for(i=0;i<10;i++)if(calg(S,i)==ret){
printf("%d\n",i);
fflush(stdout);
break;
}
int x,y;
scanf("%d%d",&x,&y);
S^=1<<getpos(x,y);
}else{
int x;
scanf("%d",&x);
ll ret=inf;
for(int i=0;i<m;i++)if(S>>i&1)ret=min(ret,calf(S^(1<<i))+x*w[i]);
//printf("->%lld\n",ret);
for(int i=0;i<m;i++)if(S>>i&1)if(ret==calf(S^(1<<i))+x*w[i]){
write(i);
S^=1<<i;
break;
}
}
}
}


J. Cherry orchard

posted @ 2018-04-11 00:36 Claris 阅读(...) 评论(...) 编辑 收藏