论文:http://wenku.baidu.com/view/4fe4ac659b6648d7c1c74633.html
hdu 4804
/*************************************************************************
> File Name: hdu4804.cpp
> Author: TechMonster
> Mail: 928221136@qq.com
> Created Time: 五 7/ 8 11:43:36 2016
************************************************************************/
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<string>
#include<math.h>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
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; }
#define ls (o<<1)
#define rs (o<<1|1)
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x, y) memcpy(x, y, sizeof(x))
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int N = 50010;
const int M = 1e9+7;
int n,m,c,d,dp[2][1100][21];
char mp[110][12];
int now,nxt;
void update(int ns,int s,int nk,int k)
{
if(ns & 1<<m)
{
ns ^= 1<<m;
dp[nxt][ns][nk] += dp[now][s][k];
if(dp[nxt][ns][nk] > M) dp[nxt][ns][nk] %= M;
}
}
void solve()
{
for(int i = 0; i < n; ++i)
scanf("%s",mp[i]);
now = 0,nxt = 1;
int top = 1<<m;
MS(dp[nxt],0);
dp[nxt][top-1][0] = 1;
for(int i = 0; i < n; ++i)
for(int j = 0; j < m; ++j)
{
nxt ^= 1; now ^= 1;
MS(dp[nxt],0);
if(mp[i][j] == '0')
{
for(int s = 0; s < top; ++s)
for(int k = 0; k <= d; ++k)
if(dp[now][s][k]) update(s<<1 | 1,s,k,k);
}
else
{
for(int s = 0; s < top; ++s)
for(int k = 0; k <= d; ++k)
{
if(!dp[now][s][k]) continue;
update(s<<1,s,k,k);
if(k < d) update(s<<1 | 1,s,k+1,k);
if(j && !(s&1)) update(s<<1 | 3, s, k,k);
if(i && !(s & 1<<m-1)) update(s<<1 ^ 1<<m ^ 1, s, k, k);
}
}
}
int ans = 0;
for(int i = c; i <= d; ++i) {
ans += dp[nxt][top-1][i];
ans %= M;
}
printf("%d\n",ans);
}
int main()
{
while(~scanf("%d%d%d%d",&n,&m,&c,&d))
solve();
return 0;
}
hdu 5286
这题其实没用插头,只用了轮廓线。
状态表示的是,该格子的前m个格子是否被覆盖,0表示没有,1表示有。
前m个是指,先往左,没格子了就从上一层的右边开始接着数
/*************************************************************************
> File Name: hdu5286.cpp
> Author: TechMonster
> Mail: 928221136@qq.com
> Created Time: 二 7/ 5 20:51:25 2016
************************************************************************/
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<string>
#include<math.h>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
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; }
#define ls (o<<1)
#define rs (o<<1|1)
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x, y) memcpy(x, y, sizeof(x))
#define PB(x) push_back(x);
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int N = 50010;
const LL M = 1000000007;
int n,m,a[N],b[N],color,vis[N],lim;
vector<LL>Pow[N];
int prefix[250][50010],belong[N];
LL sum[250][250];
void solve()
{
scanf("%d%d",&n,&m);
lim = sqrt(n);
for(int i = 1; i <= n; ++i)
{
scanf("%d",&a[i]);
b[i] = a[i];
belong[i] = i/lim + 1;
}
sort(b+1,b+1+n);
color = unique(b+1,b+1+n) - b - 1;
MS(vis,0);
for(int i = 1; i <= n; ++i)
a[i] = lower_bound(b+1,b+1+color,a[i]) - b,vis[a[i]]++;
for(int i = 1; i <= color; ++i)
{
Pow[i].clear();
Pow[i].PB(0);
LL ret = 1,p = b[i];
for(int j = 1; j <= vis[i]; ++j) ret = (ret*p)%M,Pow[i].PB(ret);
}
int top = n/lim+1,L,R;
for(int i = 1; i <= top; ++i)
{
memset(vis,0,sizeof(int)*(color+3));
L = max(1,(i-1)*lim);
R = min(n,i*lim-1);
for(int j = 1; j <= color; ++j)
prefix[i][j] = prefix[i-1][j];
for(int j = L; j <= R; ++j)
prefix[i][a[j]]++;
sum[i][belong[L]] = Pow[a[L]][1]; vis[a[L]]++;
for(int j = L+1; j <= n; ++j)
{
sum[i][belong[j]] = (sum[i][belong[j-1]] - Pow[a[j]][vis[a[j]]] + Pow[a[j]][vis[a[j]]+1])%M;
vis[a[j]]++;
}
}
int la = 0,A,B,c;
LL ret;
for(int i = 1; i <= m; ++i)
{
scanf("%d%d",&A,&B);
L = min((A^la)%n,(B^la)%n)+1;
R = max((A^la)%n,(B^la)%n)+1;
if(belong[R]-belong[L] <= 1)
{
ret = 0;
memset(vis,0,sizeof(int)*(color+3));
for(int i = L; i <= R; ++i)
{
c = a[i];
ret = (ret - Pow[c][vis[c]] + Pow[c][vis[c]+1])%M;
vis[c]++;
}
}
else
{
int l = (belong[L])*lim-1, r = belong[R]*lim - lim;
memset(vis,-1,sizeof(int)*(color+3));
ret = sum[belong[L]+1][belong[R]-1];
for(int i = L; i <= l; ++i)
{
c = a[i];
if(vis[c] == -1) vis[c] = prefix[belong[R]-1][c] - prefix[belong[L]][c];
ret = (ret - Pow[c][vis[c]] + Pow[c][vis[c]+1])%M;
vis[c]++;
}
for(int i = r; i <= R; ++i)
{
c = a[i];
if(vis[c] == -1) vis[c] = prefix[belong[R]-1][c] - prefix[belong[L]][c];
ret = (ret - Pow[c][vis[c]] + Pow[c][vis[c]+1])%M;
vis[c]++;
}
}
ret = (ret%M+M)%M;
la = ret;
printf("%d\n",la);
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
solve();
return 0;
}