T1
考虑转成切比雪夫距离后记录四个边界
d
p
dp
dp
每次暴力枚举下一个作为新边界的点
d
p
dp
dp,剩下加入点直接计算和新矩形的答案
由于显然不可能左右横跳着选,这样能把所有情况考虑进去
#include<bits/stdc++.h>
using namespace std;
#define cs const
#define re register
#define pb push_back
#define pii pair<int,int>
#define ll long long
#define y1 shinkle
#define fi first
#define se second
#define bg begin
cs int RLEN=1<<20|1;
inline char gc(){
static char ibuf[RLEN],*ib,*ob;
(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob)?EOF:*ib++;
}
inline int read(){
char ch=gc();
int res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
inline ll readll(){
char ch=gc();
ll res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
inline int readstring(char *s){
int top=0;char ch=gc();
while(isspace(ch))ch=gc();
while(!isspace(ch)&&ch!=EOF)s[++top]=ch,ch=gc();
s[top+1]='\0';return top;
}
template<typename tp>inline void chemx(tp &a,tp b){a=max(a,b);}
template<typename tp>inline void chemn(tp &a,tp b){a=min(a,b);}
cs int M=23;
int f[M][M][M][M];
int n,m,id[M][M],cnt,vs[90];
int x[90],y[90];
char s[M][M];
inline int calc(int lx,int rx,int ly,int ry,int i){
//cout<<i<<" "<<x[i]<<" "<<lx<<'\n';
return max(max(x[i]-lx,rx-x[i]),max(y[i]-ly,ry-y[i]));
}
int main(){
#ifdef Stargazer
freopen("lx.in","r",stdin);
#endif
n=read(),m=read();
memset(f,127/2,sizeof(f));int ans=f[0][0][0][0],INF=f[0][0][0][0];
for(int i=1;i<=n;i++){
readstring(s[i]);
for(int j=1;j<=m;j++)if(s[i][j]=='#'){
cnt++;
x[cnt]=i+j,y[cnt]=m+i-j+1;
f[x[cnt]][x[cnt]][y[cnt]][y[cnt]]=0;
// cout<<i+j<<" "<<m+i-j+1<<" "<<cnt<<'\n';
}
}
for(int lx=22;lx;lx--)
for(int rx=lx;rx<=22;rx++)
for(int ly=22;ly;ly--)
for(int ry=ly;ry<=22;ry++)if(f[lx][rx][ly][ry]<INF){
bool rest=0;int pv=f[lx][rx][ly][ry];
//cout<<lx<<" "<<rx<<" "<<ly<<" "<<ry<<" "<<pv<<'\n';
for(int i=1;i<=cnt;i++)vs[i]=(lx<=x[i]&&x[i]<=rx&&ly<=y[i]&&y[i]<=ry);
for(int i=1;i<=cnt;i++)if(!vs[i]){
rest=1;
int vl=calc(lx,rx,ly,ry,i),
plx=min(lx,x[i]),prx=max(rx,x[i]),ply=min(ly,y[i]),pry=max(ry,y[i]);
// cout<<i<<" "<<vl<<'\n';
for(int j=1;j<=cnt;j++)if(!vs[j]&&j!=i&&(plx<=x[j]&&x[j]<=prx&&ply<=y[j]&&y[j]<=pry)){
vl+=calc(plx,prx,ply,pry,j);
//cout<<j<<" "<<vl<<'\n';
}chemn(f[plx][prx][ply][pry],pv+vl);
}
if(!rest)chemn(ans,f[lx][rx][ly][ry]);
}cout<<ans<<'\n';
}
T2
考虑显然可以列出状态
如果没有环可以直接
d
p
dp
dp
现在有环可以先强制平局然后利用
s
p
f
a
spfa
spfa迭代
#include<bits/stdc++.h>
using namespace std;
#define cs const
#define re register
#define pb push_back
#define pii pair<int,int>
#define ll long long
#define y1 shinkle
#define fi first
#define se second
#define bg begin
cs int RLEN=1<<20|1;
inline char gc(){
static char ibuf[RLEN],*ib,*ob;
(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob)?EOF:*ib++;
}
inline int read(){
char ch=gc();
int res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
inline ll readll(){
char ch=gc();
ll res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
inline int readstring(char *s){
int top=0;char ch=gc();
while(isspace(ch))ch=gc();
while(!isspace(ch)&&ch!=EOF)s[++top]=ch,ch=gc();
s[top+1]='\0';return top;
}
template<typename tp>inline void chemx(tp &a,tp b){a=max(a,b);}
template<typename tp>inline void chemn(tp &a,tp b){a=min(a,b);}
cs int N=100005,M=200005;
struct node{
int x,y,pre,now;
};
queue<node> q;
vector<int> e[N];
int f[N][6],cnt[N][6][3];
int fak[6],bel[6],kd[6];
inline void insert(int x,int y,int now){
int pre=f[x][y];
if(pre==now)return;
q.push(node{x,y,pre,now});
f[x][y]=now;
}
inline void push(int x,int y){
int k;
if(kd[y]){
if(cnt[x][y][0])k=0;
else if(cnt[x][y][1])k=1;
else k=2;
}
else{
if(cnt[x][y][2])k=2;
else if(cnt[x][y][1])k=1;
else k=0;
}insert(x,y,k);
}
int d[N],n,m;
char str[10];
int main(){
#ifdef Stargazer
freopen("lx.in","r",stdin);
freopen("my.out","w",stdout);
#endif
n=read(),m=read();
for(int i=1;i<=m;i++){
int u=read(),v=read();
d[u]++,e[v].pb(u);
}
readstring(str);
for(int i=0;i<6;i++)bel[i]=(str[i+1]=='A');
readstring(str);
for(int i=0;i<6;i++)fak[i]=(str[i+1]=='1'),kd[i]=fak[i]^bel[i];
for(int i=1;i<=n;i++)
for(int j=0;j<6;j++){
f[i][j]=1;
cnt[i][j][1]=d[i];
}
for(int i=1;i<=n;i++)if(!d[i])for(int j=0;j<6;j++){
if(bel[j])insert(i,j,2);
else insert(i,j,0);
}
while(q.size()){
node t=q.front();q.pop();
int x=t.x,y=t.y,pre=t.pre,now=t.now;
// cout<<x<<" "<<y<<'\n';
y=(y+5)%6;
for(int v:e[x]){
cnt[v][y][pre]--,cnt[v][y][now]++;
push(v,y);
}
}
for(int i=1;i<=n;i++){
switch(f[i][0]){
case 0:putchar('A');break;
case 1:putchar('D');break;
case 2:putchar('B');break;
}
}return 0;
}
T3
考虑分析一下,只和每个点有多少个出 / 入,
=
=
= /
≠
x
\not=x
=x有关
只考虑
=
x
=x
=x怎么求,点分治后移一下项使得互相无关,然后用哈希表记一下可以
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)
#include<bits/stdc++.h>
using namespace std;
#define cs const
#define re register
#define pb push_back
#define pii pair<int,int>
#define ll long long
#define y1 shinkle
#define fi first
#define se second
#define bg begin
cs int RLEN=1<<20|1;
inline char gc(){
static char ibuf[RLEN],*ib,*ob;
(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob)?EOF:*ib++;
}
inline int read(){
char ch=gc();
int res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
inline ll readll(){
char ch=gc();
ll res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
inline int readstring(char *s){
int top=0;char ch=gc();
while(isspace(ch))ch=gc();
while(!isspace(ch)&&ch!=EOF)s[++top]=ch,ch=gc();
s[top+1]='\0';return top;
}
template<typename tp>inline void chemx(tp &a,tp b){a=max(a,b);}
template<typename tp>inline void chemn(tp &a,tp b){a=min(a,b);}
int mod;
inline int add(int a,int b){return (a+b)>=mod?(a+b-mod):(a+b);}
inline int dec(int a,int b){return (a<b)?(a-b+mod):(a-b);}
inline int mul(int a,int b){static ll r;r=(ll)a*b;return (r>=mod)?(r%mod):r;}
inline void Add(int &a,int b){a=(a+b)>=mod?(a+b-mod):(a+b);}
inline void Dec(int &a,int b){a=(a<b)?(a-b+mod):(a-b);}
inline void Mul(int &a,int b){static ll r;r=(ll)a*b;a=(r>=mod)?(r%mod):r;}
inline int ksm(int a,int b,int res=1){for(;b;b>>=1,Mul(a,a))(b&1)&&(Mul(res,a),1);return res;}
inline int Inv(int x){return ksm(x,mod-2);}
inline int fix(ll x){x%=mod;return (x<0)?x+mod:x;}
cs int N=100005;
int n,X,K;
int pw[N],ip[N],a[N];
int in[N],out[N];
vector<int> e[N];
inline void init_pw(){
pw[0]=ip[0]=1;
for(int i=1,iv=Inv(K);i<=n;i++)pw[i]=mul(pw[i-1],K),ip[i]=mul(ip[i-1],iv);
}
int siz[N],maxn,mxsz,rt;
bool vis[N];
void getrt(int u,int fa){
int son=0;siz[u]=1;
for(cs int &v:e[u])if(!vis[v]&&v!=fa){
getrt(v,u);
siz[u]+=siz[v];
chemx(son,siz[v]);
}
chemx(son,maxn-siz[u]);
if(son<mxsz)mxsz=son,rt=u;
}
pii tu[N],td[N];
struct Map {
static cs int mod = 19260817;
int val[mod],adj[mod],nxt[100005],to[100005],ecnt;
int stk[100005], top;
inline void clear() {ecnt=0;
while (top)
adj[stk[top]]=0,top--;
}
inline void update(int p, int k) {
int u = p % mod;
for(int e=adj[u];e;e=nxt[e])if(to[e]==p){
val[e]+=k;return;
}nxt[++ecnt]=adj[u],adj[u]=ecnt,to[ecnt]=p,val[ecnt]=k,stk[++top]=u;
}
inline int query(int p) {
int u=p%mod;
for(int e=adj[u];e;e=nxt[e])if(to[e]==p)return val[e];
return 0;
}
}mp1,mp2;
int tot;
void get_vl(int u,int fa,int dep,int up,int dn){
tot++;
up=add(mul(up,K),a[u]);
if(dep)dn=add(dn,mul(a[u],pw[dep-1]));
int vl=mul(dec(X,up),ip[dep+1]);
mp1.update(vl,1),mp2.update(dn,1);
tu[tot]=pii(vl,u);
td[tot]=pii(dn,u);
for(cs int &v:e[u])if(!vis[v]&&v!=fa)get_vl(v,u,dep+1,up,dn);
}
inline void calc(int u,int coef,int dep,int up,int dn=0){
tot=1;mp1.clear(),mp2.clear();
up=add(mul(up,K),a[u]);
if(dep)dn=add(dn,mul(a[u],pw[dep-1]));
tu[1]=pii(mul(dec(X,up),ip[dep+1]),u);
td[1]=pii(dn,u);
mp1.update(mul(dec(X,up),ip[dep+1]),1);
mp2.update(dn,1);
for(cs int &v:e[u])if(!vis[v])get_vl(v,u,dep+1,up,dn);
for(int i=1;i<=tot;i++){
in[td[i].se]+=coef*mp1.query(td[i].fi);
out[tu[i].se]+=coef*mp2.query(tu[i].fi);
}
}
void solve(int u,int ts){
vis[u]=1;
calc(u,1,0,0);
for(cs int &v:e[u])if(!vis[v]){
calc(v,-1,1,a[u]);
}
for(cs int &v:e[u])if(!vis[v]){
if(siz[v]>siz[u])maxn=ts-siz[u];
mxsz=1e9;
getrt(v,rt=0);
solve(v,maxn);
}
}
int main(){
#ifdef Stargazer
freopen("lx.in","r",stdin);
#endif
n=read(),mod=read(),K=read(),X=read();
init_pw();
for(int i=1;i<=n;i++)a[i]=read();
for(int i=1;i<n;i++){
int u=read(),v=read();
e[u].pb(v),e[v].pb(u);
}
maxn=n,mxsz=1e9;
getrt(1,0);
//cout<<rt<<'\n';
solve(rt,n);
ll ans=0;
for(int i=1;i<=n;i++){
ll in0=in[i],in1=n-in0,out0=out[i],out1=n-out0;
// cout<<in0<<" "<<in1<<" "<<out0<<" "<<out1<<'\n';
ans+=in0*in1*2+out0*out1*2+in0*out1+in1*out0;
}
//cout<<ans<<'\n';
ans/=2;
cout<<(ll)n*n*n-ans<<'\n';
return 0;
}