2019.10.8
T1:
在
先考虑求出
考虑求出
枚举最小值
答案就是:
于是70pts就有了
考虑容斥一下:
code:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=200010;
const ll mod=1000000007;
int n,m,x,y;
ll ans;
ll f[maxn],g[maxn],fac[maxn];
inline int read()
{
char c=getchar();int res=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')res=res*10+c-'0',c=getchar();
return res*f;
}
inline ll power(ll x,ll k)
{
ll res=1;
while(k)
{
if(k&1)res=(res*x)%mod;
x=(x*x)%mod;k>>=1;
}
return res;
}
inline ll C(int x,int y){return ((fac[x]*power(fac[x-y],mod-2))%mod*power(fac[y],mod-2))%mod;}
int main()
{
//freopen("past.in","r",stdin);
//freopen("past.out","w",stdout);
n=read(),m=read(),x=read(),y=read();
fac[0]=fac[1]=1;for(int i=2;i<=m;i++)fac[i]=(fac[i-1]*i)%mod;
//printf("%lld\n",C(2,1));
for(int i=0;i<=m;i++)f[i]=((C(m,i)*(power(x,m-i))%mod*power(y,i))%mod)%mod;
for(int i=m;i;i--)g[i-1]=(g[i]+f[i])%mod;
for(int i=1;i<=m;i++)ans=(ans+(((power(g[i-1],n)-power(g[i],n))%mod+mod)%mod)*i)%mod;
printf("%lld",ans);
return 0;
}
T2:
对
code:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1010;
const int maxq=100010;
int n,m,Q,sum;
int ans[maxq];
int a[maxn][maxn];
bool vis[maxn];
vector<int>nxt[maxq];
struct Query{int op,x,y;}qr[maxq];
inline int read()
{
char c=getchar();int res=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')res=res*10+c-'0',c=getchar();
return res*f;
}
inline void change(int id)
{
if(qr[id].op==4||!qr[id].op)return;
int op=qr[id].op,x=qr[id].x,y;
if(op==1)y=qr[id].y;
if(op==1)sum+=a[x][y]?-1:1,a[x][y]^=1;
if(op==2)
for(int i=1;i<=m;i++)
sum+=a[x][i]?-1:1,a[x][i]^=1;
if(op==3)
for(int i=1;i<=n;i++)
sum+=a[i][x]?-1:1,a[i][x]^=1;
}
void solve(int x)
{
//printf("in::%d \n",x);
change(x);ans[x]=sum;
for(unsigned int i=0;i<nxt[x].size();i++)solve(nxt[x][i]);
change(x);
//printf("out::%d\n",x);
}
int main()
{
//freopen("present.in","r",stdin);
//freopen("present.out","w",stdout);
n=read(),m=read(),Q=read();
for(int i=1;i<=Q;i++)
{
qr[i].op=read(),qr[i].x=read();
if(qr[i].op==1)qr[i].y=read();
if(qr[i].op!=4)nxt[i-1].push_back(i);
else nxt[qr[i].x].push_back(i);
}
solve(0);
//change(1);printf("%d",sum);
for(int i=1;i<=Q;i++)printf("%d\n",ans[i]);
return 0;
}
T3:
将
发现
记关键点数目为
考虑关键点的取值有
确定了关键点的值域后,考虑从小到大将值插进去,这时发现如果一个标记点没有赋值,那么它周边点必定不能赋值(把数值从小到大插入,之后必定比现在大),于是考虑状压标记点
2.这一步不放标记点
预处理
设
code:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int,int>
#define mp make_pair
#define fir first
#define sec second
const int maxn=110;
const int maxk=15;
const int mod=1e9+7;
int n,m,K,tot;
int dx[8]={-1,1,0,0,-1,1,-1,1},dy[8]={0,0,-1,1,-1,-1,1,1};
int g[1<<maxk],fac[maxn*maxn],inv[maxn*maxn];
int f[8*maxk][1<<maxk];
bool vis[maxn][maxn],check[maxn][maxn];
pii pt1[maxk];
vector<pii>pt2;
inline int power(int x,int k)
{
int res=1;
while(k)
{
if(k&1)res=(res*x)%mod;
x=(x*x)%mod;k>>=1;
}
return res;
}
signed main()
{
scanf("%lld%lld%lld",&n,&m,&K);
for(int i=1;i<=K;i++)scanf("%lld%lld",&pt1[i].fir,&pt1[i].sec),check[pt1[i].fir][pt1[i].sec]=1;
fac[0]=1;for(int i=1;i<=n*m;i++)fac[i]=(fac[i-1]*i)%mod;
inv[n*m]=power(fac[n*m],mod-2);for(int i=n*m;i;i--)inv[i-1]=(inv[i]*i)%mod;
for(int i=1;i<=K;i++)
{
int x=pt1[i].fir,y=pt1[i].sec;
for(int j=0;j<8;j++)
{
int mx=x+dx[j],my=y+dy[j];
if(mx<1||mx>n||my<1||my>m||vis[mx][my]||check[mx][my])continue;
vis[mx][my]=1;tot++;
}
}
for(int s=0;s<(1<<K);s++)
{
memset(vis,0,sizeof(vis));
int cnt=0;
for(int i=1;i<=K;i++)
{
if(s&(1<<(i-1)))continue;
int x=pt1[i].fir,y=pt1[i].sec;
for(int j=0;j<8;j++)
{
int mx=x+dx[j],my=y+dy[j];
if(mx<1||mx>n||my<1||my>m||vis[mx][my]||check[mx][my])continue;
vis[mx][my]=1;cnt++;
}
}
g[s]=tot-cnt;
}
//printf("%lld\n",tot);
/*for(int i=0;i<(1<<K);i++)printf("%d ",g[i]);
puts("---");*/
f[0][0]=1;
for(int i=0;i<tot+K;i++)
{
//printf("case::%lld ",i);
for(int s=0;s<(1<<K);s++)
{
//printf("%lld ",s);
int cnt=0;
for(int j=1;j<=K;j++)if(!(s&(1<<(j-1))))f[i+1][s|(1<<(j-1))]=(f[i+1][s|(1<<(j-1))]+f[i][s])%mod,cnt++;
cnt=K-cnt;
if(g[s]-i+cnt>0)f[i+1][s]=(f[i+1][s]+(f[i][s]*(g[s]-i+cnt+mod)%mod)%mod)%mod;
}
}
/*
for(int i=0;i<=tot;i++,puts(""))
for(int j=0;j<(1<<K);j++)
printf("%lld ",f[i][j]);
*/
//printf("%lld\n",f[tot][(1<<K)-1]);
printf("%lld",((f[tot+K][(1<<K)-1]*fac[n*m])%mod*inv[tot+K])%mod);
return 0;
}