XIX Open Cup named after E.V. Pankratiev. GP of Poland(AMPPZ-2018)

A. Drone With a Camera

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long double ld;
const ld K=1e9,inf=1e100,eps=1e-9;
const int T=200;
struct P{
ld x,y;
P(){}
P(ld _x,ld _y){x=_x,y=_y;}
}O;
struct Line{
ld a,b,c;
void init(){
double _a,_b,_c;
scanf("%lf%lf%lf",&_a,&_b,&_c);
a=_a,b=_b,c=_c;
}
P cal(ld x){
if(fabs(b)>fabs(a))return P(x,(c-a*x)/b);
return P((c-b*x)/a,x);
}
}A,B;
inline ld sqr(ld x){return x*x;}
inline ld dis(P a,P b){
return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));
}
inline ld cal(ld x,ld y){
P u=A.cal(x);
P v=B.cal(y);
return dis(O,u)+dis(u,v)+dis(v,O);
}
ld l=-K,r=K,ans=inf;
for(int i=T;i--;){
ld len=(r-l)/3;
ld m1=l+len,m2=r-len;
ld f1=cal(x,m1),f2=cal(x,m2);
ans=min(ans,min(f1,f2));
if(f1<f2)r=m2;else l=m1;
}
return ans;
}
ld l=-K,r=K,ans=inf;
for(int i=T;i--;){
ld len=(r-l)/3;
ld m1=l+len,m2=r-len;
ans=min(ans,min(f1,f2));
if(f1<f2)r=m2;else l=m1;
}
return ans;
}
int main(){
A.init();
B.init();
}


B. Fibonaccis’ vouchers

#include<cstdio>
typedef long long ll;
const ll inf=1000000000000000000LL;
const int N=150;
int cnt,i,j,k,b[N];ll a[N],n,ans;
ll f[N][N][2];
a+=b;
if(a>inf+10)return inf+10;
return a;
}
inline int cal(ll x){
int ret=0;
for(int i=cnt;i;i--)if(x>=a[i])x-=a[i],ret++;
return ret;
}
inline ll solution(int lim){
//[1..lim] are not known
int i,j,x,o;
for(i=0;i<=cnt+10;i++)for(j=0;j<=k;j++)for(o=0;o<2;o++)f[i][j][o]=0;
int _=0;
for(i=lim+1;i<=cnt;i++)if(b[i]&&b[i+1])return 0;
for(i=lim+1;i<=cnt;i++)_+=b[i];
if(_>k)return 0;
f[lim+1][_][b[lim+1]]=1;
for(i=lim+1;i>1;i--)for(j=0;j<=k;j++)for(o=0;o<2;o++)for(x=0;x<2;x++){
if(o&&x)continue;
if(j+x>k)continue;
}
ll ret=0;
return ret;
}
int main(){
a[1]=1;
a[2]=2;
for(i=3;;i++){
a[i]=a[i-1]+a[i-2];
if(a[i]<=inf)cnt=i;
else break;
}
//it should >= k
scanf("%d%lld",&k,&n);
for(i=0;i<k;i++)if(cal(i)<=k)n++;
for(i=cnt;i;i--){
for(j=0;j<2;j++){
b[i]=j;
ll tmp=solution(i-1);
//printf("%d %d %lld\n",i,j,tmp);
if(n<=tmp)break;
else{
n-=tmp;
}
}
if(j==2)return puts("NIE"),0;
}
if(ans>inf)puts("NIE");else printf("%lld",ans);
}


C. Chinese Remainder Theorem

#include<cstdio>
typedef long long ll;
int n,i;ll ans,a[111111],b[111111];
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
int main(){
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%lld",&a[i]);
for(i=1;i<=n;i++)scanf("%lld",&b[i]);
for(i=1;i<=n;i++)ans=gcd(ans,a[i]-b[i]);
printf("%lld",ans);
}


#include<cstdio>
#include<algorithm>
using namespace std;
const int N=300010,M=20000000,P=1000000007,inf=~0U>>1,inv2=(P+1)/2;
int cnt,n,m,t,x,y,z,F,G,ST;char op[9];
int T,tot,l[M],r[M],tag[M],val[M];
struct E{
int f,g,sum,st,en;
int at(int x){return (1LL*f*(x-st+1)+g)%P;}
int cal(int l,int r){return 1LL*inv2*(at(l)+at(r))%P*(r-l+1)%P;}
}e[N],now;
inline void tag1(int&x,int p){
if(!x)x=++tot;
tag[x]=max(tag[x],p);
val[x]=max(val[x],p);
}
inline void pb(int x){
if(tag[x]){
tag1(l[x],tag[x]);
tag1(r[x],tag[x]);
tag[x]=0;
}
}
void change(int&x,int a,int b,int c,int d,int p){
if(!x)x=++tot;
if(c<=a&&b<=d){
tag1(x,p);
return;
}
pb(x);
int mid=(a+b)>>1;
if(c<=mid)change(l[x],a,mid,c,d,p);
if(d>mid)change(r[x],mid+1,b,c,d,p);
val[x]=min(val[l[x]],val[r[x]]);
}
int ask(int x,int a,int b,int c,int d){
if(c<=a&&b<=d||!x)return val[x];
pb(x);
int mid=(a+b)>>1,t=inf;
return t;
}
inline int query(int L,int R){
if(L>R)return 0;
int l=1,r=cnt,mid,t=0;
now.f=F;
now.g=G;
now.st=ST;
now.en=R;
while(l<=r){
mid=(l+r)>>1;
if(e[mid].st>L)r=mid-1;
else if(e[mid].en<L)l=mid+1;
else{
t=mid;
break;
}
}
if(t==0)return now.cal(L,R);
return ((1LL*now.cal(ST,R)+1LL*e[cnt].sum-1LL*e[t].sum+1LL*e[t].cal(L,e[t].en))%P+P)%P;
}
int main(){
scanf("%d%d",&n,&m);
while(m--){
scanf("%d%s%d%d",&t,op,&x,&y);
if(op[0]=='L'){
change(T,1,n,x,y,t);
}
if(op[0]=='S'){
scanf("%d",&z);
change(T,1,n,x,y,t+z);
}
if(op[0]=='?'){
printf("%d\n",query(z+1,t));
}
if(op[0]=='B'){
e[++cnt].f=F;
e[cnt].g=G;
e[cnt].st=ST;
e[cnt].en=t;
e[cnt].sum=(e[cnt-1].sum+e[cnt].cal(e[cnt].st,e[cnt].en))%P;
ST=t+1;
F=x;
G=y;
}
}
}


E. Evaluation

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair < int, int > pii;

{
int x = 0, f = 1, c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-')
f = -1;
for (;  isdigit(c); c = getchar())
x = x * 10 + c - '0';
return x * f;
}

const int MAXN = 1000005;
const int INF = 0x3f3f3f3f;

int f[MAXN], u[MAXN], v[MAXN], w[MAXN], p[MAXN], n, m, g[18][MAXN], h[18][MAXN], dep[MAXN], ans[MAXN], e[18][MAXN];
vector < pii > adj[MAXN], a[MAXN];
bool t[MAXN];

inline int Find(int x) { while (x ^ f[x]) x = f[x] = f[f[x]]; return x; }

inline void Dfs(int x)
{
{
int y = e.xx, w = e.yy;
if (y == g[0][x])
continue;
g[0][y] = x; h[0][y] = w;
for (int i = 1; i <= 17; i ++)
g[i][y] = g[i - 1][g[i - 1][y]], h[i][y] = max(h[i - 1][y], h[i - 1][g[i - 1][y]]);
dep[y] = dep[x] + 1;
Dfs(y);
}
}

inline void Build()
{
sort(p + 1, p + m + 1, [&](int x, int y) { return w[x] < w[y]; });

for (int i = 1; i <= n; i ++)
f[i] = i;

for (int i = 1; i <= m; i ++)
{
int x = u[p[i]], y = v[p[i]], z = w[p[i]];
if (Find(x) ^ Find(y))
}

Dfs(1);
}

inline int Query(int x, int y)
{
int ret = 0;
if (dep[x] < dep[y])
swap(x, y);
if (dep[x] ^ dep[y])
for (int i = 17; ~i; i --)
if (dep[x] - dep[y] >> i & 1)
ret = max(ret, h[i][x]), x = g[i][x];
if (x == y)
return ret;
for (int i = 17; ~i; i --)
if (g[i][x] ^ g[i][y])
ret = max(ret, max(h[i][x], h[i][y])), x = g[i][x], y = g[i][y];

return max(ret, max(h[0][x], h[0][y]));
}

inline void Add(int x, int y, int w)
{
if (dep[x] < dep[y])
swap(x, y);
if (dep[x] ^ dep[y])
for (int i = 17; ~i; i --)
if (dep[x] - dep[y] >> i & 1)
e[i][x] = min(e[i][x], w), x = g[i][x];
if (x ^ y)
{
for (int i = 17; ~i; i --)
if (g[i][x] ^ g[i][y])
e[i][x] = min(e[i][x], w), e[i][y] = min(e[i][y], w), x = g[i][x], y = g[i][y];
e[0][x] = min(e[0][x], w);
e[0][y] = min(e[0][y], w);
}
}

int main()
{
#ifdef wxh010910
freopen("data.in", "r", stdin);
#endif
for (int i = 1; i <= m; i ++)

Build();

mset(e, INF);

for (int i = 1; i <= m; i ++)
if (!t[i])
ans[i] = Query(u[i], v[i]), Add(u[i], v[i], w[i]);
else if (dep[u[i]] < dep[v[i]])
f[v[i]] = i;
else
f[u[i]] = i;

for (int j = 17; j; j --)
for (int i = 1; i <= n; i ++)
e[j - 1][i] = min(e[j - 1][i], e[j][i]), e[j - 1][g[j - 1][i]] = min(e[j - 1][g[j - 1][i]], e[j][i]);

for (int i = 2; i <= n; i ++)
ans[f[i]] = e[0][i] == INF ? 1e9 : e[0][i];

for (int i = 1; i <= m; i ++)
printf("%d\n", ans[i]);

return 0;
}


F. Baking Pans

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <string>
#include <bitset>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <sstream>
#include <stack>
#include <iomanip>
using namespace std;
#define pb push_back
#define mp make_pair
typedef pair<int,int> pii;
typedef __int128 ll;
typedef double ld;
typedef vector<int> vi;
#define fi first
#define se second
#define fe first
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
#define es(x,e) (int e=fst[x];e;e=nxt[e])
#define esb(x,e,b) (int e=fst[x],b=vb[e];e;e=nxt[e],b=vb[e])
bool sol(ll p,ll d,ll t)
{
if(d+p>=t) return 0;
return p*d*4<(t-d-p)*(t-d-p);
}
int main()
{
int T; ll p,d,t;
cin>>T;
while(T--)
{
long long _,__,___;
cin>>_>>__>>___;
p=_; d=__; t=___;
if(sol(p,d,t))
puts("TAK");
else puts("NIE");
}
}


G. Taste in Art

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=50010,M=19;
int n,m,i,j,a[N],ans,o,f[2][1<<M];
struct E{int v,x,y,z;E(){}E(int _v,int _x,int _y,int _z){v=_v,x=_x,y=_y,z=_z;}}e[N],b[N];
inline bool cmp(const E&a,const E&b){
if(a.v!=b.v)return a.v<b.v;
if(a.x!=b.x)return a.x<b.x;
return a.y<b.y;
}
inline void up(int&a,int b){a<b?(a=b):0;}
inline int solve(int L,int R){
int ret=0,i,j,k,x,y,z,A,B;
if(L+1>=R){
for(i=L;i<=R;i++)ret+=e[i].z;
return ret;
}
int ymin=100;
for(i=L;i<=R;i++){
b[i]=e[i];
ymin=min(ymin,e[i].y);
}
for(i=L;i<=R;i++)b[i].y-=ymin;
o=0;
A=1;
for(j=0;j<1<<A;j++)f[0][j]=f[1][j]=-1;
f[0][0]=0;
int oldy=-1;
//puts("!");
for(i=L;i<=R;i++){
x=b[i].x,y=b[i].y,z=b[i].z;
//printf("x=%d y=%d z=%d\n",x,y,z);
B=max(A,y+1);
if(i>L&&x==b[i-1].x){
int blank=~0U>>1;
for(j=b[i-1].y+1;j<y;j++)blank^=1<<j;
for(j=0;j<1<<B;j++)f[o^1][j]=-1;
for(j=0;j<1<<A;j++)if(~f[o][j]){
k=j␣
int kk=k;
if(kk>>y&1)kk^=1<<y;
//not choose
up(f[o^1][kk],f[o][j]);
//choose
if((k>>y&1)&&(k>>(y+1)&1))continue;
up(f[o^1][kk^(1<<y)],f[o][j]+z);
}
o^=1;
A=B;
oldy=y;
}else{
int blank=~0U>>1;
for(j=oldy+1;j<A;j++)blank^=1<<j;
for(j=0;j<y;j++)blank^=1<<j;
for(j=0;j<1<<B;j++)f[o^1][j]=-1;
for(j=0;j<1<<A;j++)if(~f[o][j]){
k=j␣
int kk=k;
if(kk>>y&1)kk^=1<<y;
//not choose
up(f[o^1][kk],f[o][j]);
//choose
if((k>>y&1)&&(k>>(y+1)&1))continue;
up(f[o^1][kk^(1<<y)],f[o][j]+z);
}
o^=1;
A=B;
oldy=y;
}
}
for(j=0;j<1<<A;j++)up(ret,f[o][j]);
return ret;
}
//[0..18]
int main(){
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d",&a[i]);
sort(a+1,a+n+1);
for(i=1;i<=n;i=j){
for(j=i;j<=n&&a[i]==a[j];j++);
int v=a[i],x=0,y=0;
while(v%2==0)v/=2,x++;
while(v%3==0)v/=3,y++;
e[++m]=E(v,x,y,j-i);
}
sort(e+1,e+m+1,cmp);
for(i=1;i<=m;i=j){
for(j=i+1;j<=m;j++){
if(e[j].v!=e[j-1].v)break;
if(e[j-1].x+1<e[j].x)break;
if(e[j-1].x+1==e[j].x&&e[j-1].y<e[j].y)break;
}
ans+=solve(i,j-1);
}
printf("%d",ans);
}


H. Hobby

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=111;
int va,vb,vc,v1,v2,v3,v4,i,q[N];
char a[N][N];
int s[N];
bool check(){
if(q[1]+q[2]+q[4]+q[5]!=v1)return 0;
if(q[2]+q[3]+q[5]+q[6]!=v2)return 0;
if(q[4]+q[5]+q[7]+q[8]!=v3)return 0;
if(q[5]+q[6]+q[8]+q[9]!=v4)return 0;
s[0]=s[1]=s[2]=0;
s[a[1][1]-'A']+=q[1];
s[a[1][2]-'A']+=q[2];
s[a[1][3]-'A']+=q[3];
s[a[2][1]-'A']+=q[4];
s[a[2][2]-'A']+=q[5];
s[a[2][3]-'A']+=q[6];
s[a[3][1]-'A']+=q[7];
s[a[3][2]-'A']+=q[8];
s[a[3][3]-'A']+=q[9];
if(s[0]!=va)return 0;
if(s[1]!=vb)return 0;
if(s[2]!=vc)return 0;
return 1;
}
int main(){
scanf("%d%d%d%d%d%d%d",&va,&vb,&vc,&v1,&v2,&v3,&v4);
for(i=1;i<=3;i++)scanf("%s",a[i]+1);
for(i=1;i<=9;i++)q[i]=i;
do{
if(check()){
for(i=1;i<=9;i++){
printf("%d",q[i]);
if(i%3==0)puts("");
}
return 0;
}
}while(next_permutation(q+1,q+10));
puts("NIE");
}


• $t_j-p_j\geq t_i-p_i$
• $t_j+p_j\geq t_i+p_i$

#include<cstdio>
#include<algorithm>
#include<set>
using namespace std;
int n,i;set<int>T;
struct P{int x,y;}a[2222222];
inline bool cmp(const P&a,const P&b){
if(a.x!=b.x)return a.x<b.x;
return a.y>b.y;
}
int main(){
scanf("%d",&n);
for(i=1;i<=n;i++){
int p,t;
scanf("%d%d",&p,&t);
a[i].x=p+t;
a[i].y=p-t;
}
sort(a+1,a+n+1,cmp);
for(i=1;i<=n;i++){
int x=a[i].y;
set<int>::iterator it=T.lower_bound(x);
if(it!=T.end())T.erase(it);
T.insert(x);
}
printf("%d",(int)T.size());
}


J. Identical Scarves

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=100010;
int n,i,j,a[N],ans;ll lim,s[N];
inline ll cal(int l,int r){
int m=(l+r)/2;
return s[r]-s[m]-1LL*(r-m)*a[m]+1LL*(m-l+1)*a[m]-s[m]+s[l-1];
}
int main(){
scanf("%d%lld",&n,&lim);
for(i=1;i<=n;i++)scanf("%d",&a[i]);
sort(a+1,a+n+1);
for(i=1;i<=n;i++)s[i]=s[i-1]+a[i];
for(i=1;i<=n;i++){
while(j<n&&cal(i,j+1)<=lim)j++;
ans=max(ans,j-i+1);
}
printf("%d",ans);
}


K. Pocket Money

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <string>
#include <bitset>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <sstream>
#include <stack>
#include <iomanip>
using namespace std;
#define pb push_back
#define mp make_pair
typedef pair<int,int> pii;
typedef long long ll;
typedef double ld;
typedef vector<int> vi;
#define fi first
#define se second
#define fe first
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
#define es(x,e) (int e=fst[x];e;e=nxt[e])
#define esb(x,e,b) (int e=fst[x],b=vb[e];e;e=nxt[e],b=vb[e])
#define SZ 1234567
char s[SZ],w[SZ]; int n;
vector<int> es;
const int M=1048576;
pii g[3][M+M+3];
pii operator + (pii a,pii b)
{
return mp(min(a.fi,a.se+b.fi),a.se+b.se);
}
pii qry(pii*a,int l,int r)
{
pii L(0,0),R(0,0);
if(l>r) return L;
for(l+=M-1,r+=M+1;l^r^1;l>>=1,r>>=1)
{
if(~l&1) L=L+a[l^1];
if(r&1) R=a[r^1]+R;
}
return L+R;
}
ll chk(int pos,int neg)
{
if(pos+neg>int(es.size()))
return 0;
for(int i=1;i<=n;++i)
w[i]=(s[i]=='_')?'0':s[i];
for(int i=0;i<pos;++i)
w[es[i]]='+';
for(int i=0;i<neg;++i)
w[es[es.size()-i-1]]='-';
int g=0; ll su=1;
for(int i=1;i<=n;++i)
{
if(w[i]=='+') ++g;
else if(w[i]=='-') --g;
if(g<0) return 0; su+=g;
}
return su;
}
void wo(pii*t)
{
for(int i=M-1;i>=1;--i)
t[i]=t[i+i]+t[i+i+1];
}
pii ys[2333];
bool chk(int l,int i,pii cur,int w)
{
//	cerr<<l<<','<<i<<":"<<cur.fi<<","<<cur.se<<" "<<w<<"\n";
if(abs(w)+i+1>es.size()) return 0;
int p=abs(w),q=p-w;
int _=(es.size()-i-1-p-q)/2;p+=_;q+=_;
int r=es.size()-i-1-p-q;
//	cerr<<p<<","<<q<<" "<<p+q<<" "<<es.size()-i-1<<" "<<i<<"w"<<es.size()<<"G\n";
if(p)
i+=p,cur=cur+qry(g[0],l,es[i]),l=es[i]+1;
if(r)
i+=r,cur=cur+qry(g[1],l,es[i]),l=es[i]+1;
if(q)
i+=q,cur=cur+qry(g[2],l,es[i]),l=es[i]+1;
cur=cur+qry(g[2],es[i]+1,n);
return cur.fi>=0;
}
int main()
{
ys['+']=mp(0,1);
ys['-']=mp(-1,-1);
ys['0']=mp(0,0);
scanf("%s",s+1); n=strlen(s+1);
int t=0,em=0;
for(int i=1;i<=n;++i)
if(s[i]=='+') --t;
else if(s[i]=='-') ++t;
else if(s[i]=='0');
else ++em,es.pb(i);
for(int i=1;i<=n;++i)
g[0][i+M]=ys[(s[i]=='_')?'+':s[i]];
for(int i=1;i<=n;++i)
g[1][i+M]=ys[(s[i]=='_')?'0':s[i]];
for(int i=1;i<=n;++i)
g[2][i+M]=ys[(s[i]=='_')?'-':s[i]];
wo(g[0]);wo(g[1]);wo(g[2]);
//pos-neg=t
if(abs(t)>em)
{
puts("NIE");
return 0;
}
int p=max(t,0),q=p-t;
int w=(em-p-q)/2;
p+=w; q+=w;
ll u=chk(p,q);
if(!u)
{
puts("NIE");
return 0;
}
//cerr<<"++\n";
pii su(0,0);
int r=1,gg=0; ll sb=0;
for(int i=0;i<es.size();++i)
{
int x=es[i];
while(r<x)
su=su+ys[s[r++]],
//cerr<<r-1<<" "<<su.fi<<","<<su.se<<"\n",
sb+=su.se;
r=x+1;
char u[3]={'-','0','+'};
for(auto p:u)
{
pii sw=su+ys[p];
if(chk(x+1,i,sw,t-gg-ys[p].se))
{
s[x]=p; su=sw; gg+=ys[p].se;
sb+=su.se; break;
}
}
//cout<<x<<"!"<<s[x]<<"\n";
if(s[x]=='_') throw "GG";
}
while(r<=n)
su=su+ys[s[r++]],sb+=su.se;
//	puts(s+1);
printf("%lld ",sb);
printf("%lld\n",u-1);
}


L. Lines

#include<cstdio>
const int N=310;
int inv2;
int n,P,i,j,k,x,y,C[N][N],p[N*N],ans;
int f[N][N][N],g[N][N][N],v[3][3];
int pow(int a,int b){int t=1;for(;b;b>>=1,a=1LL*a*a%P)if(b&1)t=1LL*t*a%P;return t;}
inline void up(int&a,int b){a=(a+b)%P;}
int cal1(){
f[0][0][0]=(P-2)%P;
for(i=0;i<n;i++)for(j=0;j<=i;j++)for(k=0;k<=i;k++){
up(f[i+1][j][k],1LL*f[i][j][k]*inv2%P);
up(f[i+1][j+1][k],P-f[i][j][k]);
up(f[i+1][j][k+1],P-f[i][j][k]);
up(f[i+1][j+1][k+1],f[i][j][k]);
}
int ret=0;
for(i=0;i<=n;i++)for(j=0;j<=n;j++)up(ret,1LL*f[n][i][j]*p[(n-i)*(n-j)]%P);
return ret;
}
int cal2(){
g[0][0][0]=2;
g[1][0][0]=1;
g[1][0][1]=g[1][1][0]=(P-2)%P;
g[1][1][1]=2;
//when n is even and i=j=0, it is different
for(x=0;x<3;x++)for(y=0;y<3;y++){
int tmp=C[2][x]*C[2][y]%P;
if((x+y)&1)tmp=(P-tmp)%P;
int cnt=(2-x)*(2-y);
while(cnt--)tmp=1LL*tmp*inv2%P;
v[x][y]=tmp;
}
for(i=0;i<n;i++)for(j=0;j<=i;j++)for(k=0;k<=i;k++)
for(x=0;x<3;x++)for(y=0;y<3;y++)
up(g[i+2][j+x][k+y],1LL*v[x][y]*g[i][j][k]%P);
int ret=0;
if(n&1){
for(i=0;i<=n;i++)for(j=0;j<=n;j++)up(ret,1LL*g[n][i][j]*p[(n-i)*(n-j)]%P);
}else{
for(i=0;i<=n;i++)for(j=0;j<=n;j++)if(i||j)up(ret,1LL*g[n][i][j]*p[(n-i)*(n-j)]%P);
up(ret,p[n*n-n-n+2]);
}
return ret;
}
int main(){
scanf("%d%d",&n,&P);
if(P==2)return puts("0"),0;
inv2=pow(2,P-2);
for(p[0]=i=1;i<=n*n;i++)p[i]=p[i-1]*2%P;
for(C[0][0]=i=1;i<=n||i<=2;i++)for(C[i][0]=j=1;j<=i;j++)C[i][j]=(C[i-1][j-1]+C[i-1][j])%P;
//no diagonals
for(i=0;i<=n;i++)for(j=0;j<=n;j++){
int tmp=1LL*C[n][i]*C[n][j]%P*p[(n-i)*(n-j)]%P;
if(!i||!j)tmp=1LL*tmp*p[i+j]%P;else tmp=tmp*2%P;
if((i+j)&1)tmp=(P-tmp)%P;
up(ans,tmp);
}
up(ans,2LL*cal1()%P);
up(ans,cal2());
printf("%d",(ans%P+P)%P);
}


M. Magical Maze

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=500010;
char tmp[N];long long ans;
int n,m,i,j,k,x,s[N],fl[N][4],fr[N][4],dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
bool d[N][4],v1[N],v2[N],visl[N][4],visr[N][4];
/*
0
3 1
2
*/
inline int id(int x,int y){
if(x<1||x>n||y<1||y>m)return 0;
return (x-1)*m+y;
}
void dfs1(int x,int y){
int z=id(x,y);
if(v1[z])return;
v1[z]=1;
for(int i=0;i<4;i++)if(d[z][i])dfs1(x+dx[i],y+dy[i]);
}
void dfs2(int x,int y){
int z=id(x,y);
if(v2[z])return;
v2[z]=1;
for(int i=0;i<4;i++)if(d[id(x-dx[i],y-dy[i])][i])dfs2(x-dx[i],y-dy[i]);
}
int dpl(int x,int y,int k){//left hand on the kth wall，后退到不能再后退（即顶点）
int z=id(x,y);
if(visl[z][k])return fl[z][k];
visl[z][k]=1;
int&ret=fl[z][k];
ret=0;
if(x==n&&y==m&&(k==1||k==2))return ret;
if(d[z][k])return ret=dpl(x+dx[k],y+dy[k],(k+3)&3);
if(k==0)ret+=s[id(x,y)];
if(k==2)ret-=s[id(x+1,y)];
return ret+=dpl(x,y,(k+1)&3);
}
int dpr(int x,int y,int k){//right hand on the kth wall，后退到不能再后退（即顶点）
int z=id(x,y);
if(visr[z][k])return fr[z][k];
visr[z][k]=1;
int&ret=fr[z][k];
ret=0;
if(x==n&&y==m&&(k==1||k==2))return ret;
if(d[z][k])return ret=dpr(x+dx[k],y+dy[k],(k+1)&3);
if(k==0)ret+=s[id(x,y)];
if(k==2)ret-=s[id(x+1,y)];
return ret+=dpr(x,y,(k+3)&3);
}
int main(){
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
if(m>1)scanf("%s",tmp+1);
for(j=1;j<m;j++){
if(tmp[j]=='>')d[id(i,j)][1]=1;
if(tmp[j]=='<')d[id(i,j+1)][3]=1;
}
if(i==n)continue;
scanf("%s",tmp+1);
for(j=1;j<=m;j++){
if(tmp[j]=='v')d[id(i,j)][2]=1;
if(tmp[j]=='^')d[id(i+1,j)][0]=1;
}
}
dfs1(1,1);
dfs2(n,m);
for(i=1;i<=n;i++)for(j=1;j<=m;j++)v1[id(i,j)]&=v2[id(i,j)];
for(i=1;i<=n;i++)for(j=1;j<=m;j++){
x=id(i,j);
if(!v1[x])for(k=0;k<4;k++)d[x][k]=0;
for(k=0;k<4;k++)if(!v1[id(i+dx[k],j+dy[k])])d[x][k]=0;
}
for(i=n;i;i--)for(j=1;j<=m;j++)s[id(i,j)]=s[id(i+1,j)]+v1[id(i,j)];
for(i=1;i<=n;i++)for(j=1;j<=m;j++){
x=id(i,j);
if(!v1[x])continue;
ans+=max(dpl(i,j,0)+dpr(i,j,3),dpl(i,j,2)+dpr(i,j,1));
}
printf("%lld",ans);
}


posted @ 2018-11-13 19:27  Claris  阅读(...)  评论(... 编辑 收藏