#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
using namespace std;
//hdu 5113 搜索
//这道题就是搜索,剪枝优化是如果当前未染色的点数为x,(x+1)/2<max(col[i]),就可以return了。
int n,m,k;
int flag;
int map[6][6];
int ca;
struct sa{
int num,index;
}a[130];
int cmp(const sa a,const sa b)
{
return (a.num)>(b.num);
}
void ccout()
{
printf("Case #%d:\nYES\n",ca);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if( j==m)printf("%d\n",map[i][j]);
else printf("%d ",map[i][j]);
}
void dfs(int x,int y)
{
for(int i=1;i<=k;i++)
if(flag==-1)
return;
else
if(a[i].num)
{
if(map[x-1][y]!=a[i].index&&map[x][y-1]!=a[i].index)
{
a[i].num--;
map[x][y]=a[i].index;
if(x==n&&y==m&&flag!=-1)
{
flag=-1;
ccout();
return;
}
if(y==m)
dfs(x+1,1);
else
dfs(x,y+1);
a[i].num++;
}
}
}
int main()
{
int t;
cin>>t;
for(int i=1;i<=t;++i)
{
ca=i;
cin >>n>>m>>k;
for(int _i=1;_i<=k;++_i)
{
cin>>a[_i].num;
a[_i].index=_i;
}
sort(a+1,a+k+1,cmp);
if(a[1].num>(n*m+1)/2)
{
printf("Case #%d:\nNO\n",i);
continue;
}
flag=0;
dfs(1,1);
}
return 0;
}
//poj 2352 stars 树状数组
int level[40005],sum[40005];//sum[i]中装的是x不大于i的点的个数
int lowbit(int i)
{ return i&(-i);
}
int getsum(int i)
{
int s=0;
for(;i>0;i-=lowbit(i))
s+=sum[i];
return s;
}
void update(int x)
{
while(x<40005)
{
sum[x]++;
x+=lowbit(x);
}
}
int main()
{
int n,x,y;
while(scanf("%d",&n)!=-1)
{
memset(sum,0,sizeof(sum));
memset(level,0,sizeof(level));
for(int i=0;i<n;i++)
{
scanf("%d%d",&x,&y);
level[getsum(x+1)]++;
update(x+1);
}
for(int i=0;i<n;++i)
printf("%d\n",level[i]);
}
return 0;
}
//RMQ POJ3264
#define MAXN 200005
#define INF 10000000
int nMax,nMin;//记录最大最小值
struct Node
{
int l,r;//区间的左右端点
int nMin,nMax;//区间的最小值和最大值
}segTree[MAXN*3];
int a[MAXN];
void Build(int i,int l,int r)//在结点i上建立区间为(l,r)
{
segTree[i].l=l;
segTree[i].r=r;
if(l==r)//叶子结点
{
segTree[i].nMin=segTree[i].nMax=a[l];
return;
}
int mid=(l+r)>>1;
Build(i<<1,l,mid);
Build(i<<1|1,mid+1,r);
segTree[i].nMin=min(segTree[i<<1].nMin,segTree[i<<1|1].nMin);
segTree[i].nMax=max(segTree[i<<1].nMax,segTree[i<<1|1].nMax);
}
void Query(int i,int l,int r)//查询结点i上l-r的最大值和最小值
{
if(segTree[i].nMax<=nMax&&segTree[i].nMin>=nMin) return;
if(segTree[i].l==l&&segTree[i].r==r)
{
nMax=max(segTree[i].nMax,nMax);
nMin=min(segTree[i].nMin,nMin);
return;
}
int mid=(segTree[i].l+segTree[i].r)>>1;
if(r<=mid) Query(i<<1,l,r);
else if(l>mid) Query(i<<1|1,l,r);
else
{
Query(i<<1,l,mid);
Query(i<<1|1,mid+1,r);
}
}
int main()
{
int n,q;
int l,r;
int i;
while(scanf("%d%d",&n,&q)!=EOF)
{
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
Build(1,1,n);
for(i=1;i<=q;i++)
{
scanf("%d%d",&l,&r);
nMax=-INF;nMin=INF;
Query(1,l,r);
printf("%d\n",nMax-nMin);
}
}
return 0;
}
//poj 2528
//海报重叠
int n,cnt;
const int maxn = 10000+10;
struct node
{
int l,r,n;//n统计颜色
} a[maxn<<2];
struct kode
{
int point,num;//point记录区间的边,num记录位置
} s[maxn<<2];
int map[maxn<<1][2],ans,flag[maxn<<1];
int cmp(kode x,kode y)
{
return x.point<y.point;
}
void init(int l,int r,int i)//建树
{
a[i].l = l;
a[i].r = r;
a[i].n = 0;
if(l!=r)
{
int mid = (l+r)>>1;
init(l,mid,2*i);
init(mid+1,r,2*i+1);
}
}
void insert(int i,int l,int r,int m)
{
if(a[i].l == l && a[i].r == r)//找到了区间,更新这个区间的颜色
{
a[i].n = m;
return;
}
int mid = (a[i].l+a[i].r)>>1;
if(a[i].n>0)//重点注意,如果这个区间被访问了,并且这个区间有颜色,就要将这个区间的颜色更新到其左右孩子的节点,并且要将这个区间的颜色清空,这样才能算是覆盖
{
a[2*i].n = a[2*i+1].n = a[i].n;
a[i].n = 0;
}
if(l>=a[2*i+1].l)
insert(2*i+1,l,r,m);
else if(r<=a[2*i].r)
insert(2*i,l,r,m);
else
{
insert(2*i,l,mid,m);
insert(2*i+1,mid+1,r,m);
}
}
void solve(int i)
{
if(a[i].n)//如果有这个区间有颜色了,马上停止访问并返回,因为下面的无论有没有颜色都是已经被覆盖的了
{
if(!flag[a[i].n])//如果有颜色且没被统计过的,就统计一次
{
ans++;
flag[a[i].n] = 1;
}
return;
}
solve(2*i);
solve(2*i+1);
return;
}
int main()
{
int t,i,j;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i = 0; i<n; i++)//离散化
{
scanf("%d%d",&map[i][0],&map[i][1]);
s[2*i].point = map[i][0];
s[2*i+1].point = map[i][1];
s[2*i].num = -(i+1);
s[2*i+1].num = i+1;
}
sort(s,s+2*n,cmp);
int tmp = s[0].point,cnt = 1;
for(i = 0; i<2*n; i++)
{
if(tmp != s[i].point)//如果和前面的不同,这迭代加1
{
cnt++;
tmp = s[i].point;
}
if(s[i].num<0)
map[-s[i].num-1][0] = cnt;
else
map[s[i].num-1][1] = cnt;
}
init(1,cnt,1);
for(i = 0; i<n; i++)
insert(1,map[i][0],map[i][1],i+1);
memset(flag,0,sizeof(flag));
ans = 0;
solve(1);
printf("%d\n",ans);
}
return 0;
}
//poj 3468线段树+区间更新
#define MAX 110000
#define LL long long
using namespace std;
LL n,m;
LL ans;
struct Tree
{
LL l,r;
LL sum,add;
};
Tree tree[MAX*3];
void pushup(LL x)
{
LL tmp=2*x;
tree[x].sum=tree[tmp].sum+tree[tmp+1].sum;
}
void pushdown(LL x)
{
LL tmp=2*x;
tree[tmp].add+=tree[x].add;
tree[tmp+1].add+=tree[x].add;
tree[tmp].sum+=tree[x].add*(tree[tmp].r-tree[tmp].l+1);
tree[tmp+1].sum+=tree[x].add*(tree[tmp+1].r-tree[tmp+1].l+1);
tree[x].add=0;
}
void build(int l,int r,int x)
{
tree[x].l=l;
tree[x].r=r;
tree[x].add=0;
if(l==r)
{
scanf("%lld",&tree[x].sum);
return ;
}
int tmp=x<<1;
int mid=(l+r)>>1;
build(l,mid,tmp);
build(mid+1,r,tmp+1);
pushup(x); //如果在建树的过程中给sum赋值,记得后面要pushup
}
void update(LL l,LL r,LL c,LL x)
{
if(r<tree[x].l||l>tree[x].r)
return ;
if(l<=tree[x].l&&r>=tree[x].r)
{
tree[x].add+=c;
tree[x].sum+=c*(tree[x].r-tree[x].l+1);
return ;
}
if(tree[x].add)
pushdown(x);
LL tmp=x<<1;
update(l,r,c,tmp); // !!!
update(l,r,c,tmp+1);
pushup(x);
}
void query(LL l,LL r,LL x)
{
if(r<tree[x].l||l>tree[x].r) //要更新的区间不在该区间上
return ;
if(l<=tree[x].l&&r>=tree[x].r) //要更新区间包括了该区间
{
ans+=tree[x].sum;
return ;
}
if(tree[x].add)
pushdown(x);
LL tmp=x<<1;
LL mid=(tree[x].l+tree[x].r)>>1;
if(r<=mid)
query(l,r,tmp);
else if(l>mid)
query(l,r,tmp+1);
else
{
query(l,mid,tmp);
query(mid+1,r,tmp+1);
}
// pushup(x);
}
int main()
{
// freopen("cin.txt","r",stdin);
// freopen("cout.txt","w",stdout);
while(~scanf("%lld %lld",&n,&m))
{
build(1,n,1);
char str[5];
while(m--)
{
scanf("%s",str);
if(str[0]=='Q')
{
LL l,r;
scanf("%lld %lld",&l,&r);
ans=0;
query(l,r,1);
printf("%lld\n",ans);
}
else
{
LL l,r,c;
scanf("%lld %lld %lld",&l,&r,&c);
update(l,r,c,1);
}
}
}
return 0;
}
//hdu 3308线段树区间合并
#define N 100010
int s[N<<2],mm[N<<2],lm[N<<2],rm[N<<2],len[N<<2];
void update(int l,int r,int w)
{
int m = (l+r)>>1;
if(s[m]<s[m+1])
{
lm[w] = (lm[w<<1]==len[w<<1])?(lm[w<<1]+lm[w<<1|1]):lm[w<<1];
rm[w] = (rm[w<<1|1]==len[w<<1|1])?(rm[w<<1|1]+rm[w<<1]):rm[w<<1|1];
mm[w] = max((rm[w<<1]+lm[w<<1|1]),mm[w<<1]);
mm[w] = max(lm[w],mm[w]);
mm[w] = max(rm[w],mm[w]);
mm[w] = max(mm[w<<1|1],mm[w]);
}
else
{
lm[w] = lm[w<<1];
rm[w] = rm[w<<1|1];
mm[w] = max(mm[w<<1],mm[w<<1|1]);
}
}
int search(int a,int b,int l,int r,int w)
{
if(a<=l&&b>=r)
{
return mm[w];
}
int m = (l+r)>>1;
if(b<=m)
return search(a,b,l,m,w<<1);
if(a>m)
return search(a,b,m+1,r,w<<1|1);
int len,ren,ans ;
len = search(a,b,l,m,w<<1);
ren = search(a,b,m+1,r,w<<1|1);
ans = max(len,ren);
if(s[m]<s[m+1])
{
int re;
re=min(rm[w<<1],m-a+1)+min(lm[w<<1|1],b-m);
ans=max(re,ans);
}
return ans;
}
void build(int l,int r,int w)
{
len[w] = (r-l+1);
if(l==r)
{
mm[w] = 1;
lm[w] = 1;
rm[w] = 1;
return ;
}
int m = (l+r)>>1;
build(l,m,w<<1);
build(m+1,r,w<<1|1);
update(l,r,w);
}
void change(int p,int d,int l,int r,int w)
{
if(l==r&&l==p)
{
return ;
}
int m = (l+r)>>1;
if(p<=m)
change(p,d,l,m,w<<1);
else
change(p,d,m+1,r,w<<1|1);
update(l,r,w);
}
int main()
{
int i,j,k,n,m,t,a,b;
char c;
cin>>t;
while(t--)
{
cin>>n>>m;
for(i = 1; i <= n ; i++)
scanf("%d",&s[i]);
build(1,n,1);
while(m--)
{
cin>>c>>a>>b;
if(c=='U')
{
s[a+1] = b;
change(a+1,b,1,n,1);
}
else
{
cout<<search(a+1,b+1,1,n,1)<<endl;
}
}
}
return 0;
}
/*
注意两个地方 向上更新 和查找的时候
向上更新
1. 左儿子最右边的值 < 右儿子最左边的值
lMax = (左儿子的lMax == 左儿子的len) ? 左儿子的len + 右儿子的lMax : 左儿子的lMax;
rMax = (右儿子的rMax == 右儿子的len) ? 右儿子的len + 左儿子的rMax : 右儿子的rMax;
Max = MAX(左儿子的rMax + 右儿子的lMax, 左儿子的Max, 右儿子的Max, lMax, rMax);
2. 左儿子最右边的值 >= 右儿子最左边的值
lMax = 左儿子的lMax;
rMax = 右儿子的rMax;
Max = MAX(左儿子的Max, 右儿子的Max);
查找的时候 也分开来比较
*/
// ac自动机hdu2896
struct Trie
{
int next[210*500][128],fail[210*500],end[210*500];
int root,L;
int newnode()
{
for(int i = 0;i < 128;i++)
next[L][i] = -1;
end[L++] = -1;
return L-1;
}
void init()
{
L = 0;
root = newnode();
}
void insert(char s[],int id)
{
int len = strlen(s);
int now = root;
for(int i = 0;i < len;i++)
{
if(next[now][s[i]] == -1)
next[now][s[i]] = newnode();
now=next[now][s[i]];
}
end[now]=id;
}
void build()
{
queue<int>Q;
fail[root] = root;
for(int i = 0;i < 128;i++)
if(next[root][i] == -1)
next[root][i] = root;
else
{
fail[next[root][i]] = root;
Q.push(next[root][i]);
}
while(!Q.empty())
{
int now = Q.front();
Q.pop();
for(int i = 0;i < 128;i++)
if(next[now][i] == -1)
next[now][i] = next[fail[now]][i];
else
{
fail[next[now][i]] = next[fail[now]][i];
Q.push(next[now][i]);
}
}
}
bool used[510];
bool query(char buf[],int n,int id)
{
int len = strlen(buf);
int now = root;
memset(used,false,sizeof(used));
bool flag = false;
for(int i = 0;i < len;i++)
{
now = next[now][buf[i]];
int temp = now;
while(temp != root)
{
if(end[temp] != -1)
{
used[end[temp]] = true;
flag = true;
}
temp = fail[temp];
}
}
if(!flag)return false;
printf("web %d:",id);
for(int i = 1;i <= n;i++)
if(used[i])
printf(" %d",i);
printf("\n");
return true;
}
};
char buf[10010];
Trie ac;
int main()
{
int n,m;
while(scanf("%d",&n) != EOF)
{
ac.init();
for(int i = 1;i <= n;i++)
{
scanf("%s",buf);
ac.insert(buf,i);
}
ac.build();
int ans = 0;
scanf("%d",&m);
for(int i = 1;i <= m;i++)
{
scanf("%s",buf);
if(ac.query(buf,n,i))
ans++;
}
printf("total: %d\n",ans);
}
return 0;
}
//hdu 5384 ac自动机
struct Trie
{
int next[100010][26],fail[210*500],end[210*500];
int root,L;
int newnode()
{
for(int i = 0;i < 26;i++)
next[L][i] = -1;
end[L++] = 0;
return L-1;
}
void init()
{
L = 0;
root = newnode();
}
void insert(string buf)
{
int len = buf.size();
int now = root;
for(int i = 0;i < len;i++)
{
if(next[now][buf[i]-'a'] == -1)
next[now][buf[i]-'a'] = newnode();
now=next[now][buf[i]-'a'];
}
end[now]++;
}
void build()
{
queue<int>Q;
fail[root] = root;
for(int i = 0;i < 26 ; i++)
if(next[root][i] == -1)
next[root][i] = root;
else
{
fail[next[root][i]] = root;
Q.push(next[root][i]);
}
while(!Q.empty())
{
int now = Q.front();
Q.pop();
for(int i = 0;i < 26;i++)
if(next[now][i] == -1)
next[now][i] = next[fail[now]][i];
else
{
fail[next[now][i]] = next[fail[now]][i];
Q.push(next[now][i]);
}
}
}
int query(string buf)
{
int len = buf.size();
int now = root;
int ans = 0;
for(int i = 0;i < len;i++)
{
now = next[now][buf[i]-'a'];
int temp = now;
while(temp != root)
{
if(end[temp] != root)
ans+=end[temp];
temp = fail[temp];
}
}
return ans;
}
};
string buf[10010];
Trie ac;
int main()
{
//ios::sync_with_stdio(false);
int n,m,T;
cin>>T;
while(T--)
{
cin>>n>>m;
for(int i=0;i<n;i++)
cin>>buf[i];
ac.init();
for(int i=0;i<m;i++)
{
string s;
cin>>s;
ac.insert(s);
}
ac.build();
for(int i=0;i<n;i++)
cout<<ac.query(buf[i])<<endl;
}
return 0;
}
// 马拉车 回文串hdu3068
#define MAX 110010
char str[MAX],str1[2*MAX];
int mana[2*MAX];
int len;
int ans;
void manacher()
{
int i,j,k;
memset(mana,0,sizeof(mana));
str1[0]='&';
for(i=0,j=1;str[i]!=0;i++)
{
str1[j++]='#';
str1[j++]=str[i];
}
str1[j++]='#';
str1[j]='*';
len=j;
i=1;
int mx=0,id;
ans=0;
for(i=1;i<len;i++)
{
if(mx>i) mana[i]=min(mx-i,mana[2*id-i]);
else mana[i]=1;
for(;str1[i-mana[i]]==str1[i+mana[i]];mana[i]++);
if(mana[i]+i>mx)
{
mx=mana[i]+i;
id=i;
}
if(mana[i]>ans)
ans=mana[i];
}
}
int main(int argc, const char * argv[]) {
// insert code here...
while(scanf("%s",str)!=-1)
{
//memset(tmp,0,sizeof(tmp));
//int l = init(str);
manacher();
cout<<ans-1<<endl;
//memset(str,0,sizeof(str));
}
//std::cout << "Hello, World!\n";
return 0;
}
//2 3 4 4 3 2 2 3 4回文串
//hdu 5371
const int maxn=210001;
int s[maxn],a[maxn];
int r[maxn],len;
void Manancher()
{
int l=0;
a[l++]=-2;
a[l++]=-1;
for(int i=0;i<len;i++)
{
a[l++]=s[i];
a[l++]=-1;
}
a[l]=-3;
int mx=0,id=0;
for(int i=0;i<l;i++)
{
r[i]=mx>i?min(r[2*id-i],mx-i):1;
while(a[i+r[i]]==a[i-r[i]])r[i]++;
if(i+r[i]>mx)
{
mx=i+r[i];
id=i;
}
//printf("%d ",r[i]);
}
// printf("\n");
}
int main()
{
int T,tt=0;
scanf("%d",&T);
while(T--)
{
scanf("%d",&len);
for(int i=0;i<len;i++)
{
scanf("%d",&s[i]);
}
Manancher();
int ans=0;
for(int i=1;i<=len*2+1;i+=2)
{
for(int j=i+r[i]-1;j-i>ans;j-=2)
{
if(j-i+1<=r[j])
{
ans=max(ans,j-i);
break;
}
}
}
printf("Case #%d: %d\n",++tt,ans/2*3);
}
return 0;
}
//hdu 4513 完美队列
const int oo=0x3f3f3f3f;
//const lld OO=1LL<<61;
const int MOD=10007;
const int maxn=200010;
int h[maxn],n,len;
int p[maxn];
int Manacher()
{
int mx=0,id=0;
for(int i=1;i<=len;i++)
{
if(mx>i)
p[i]=min(mx-i,p[2*id-i]);
else
p[i]=1;
while(h[i+p[i]]==h[i-p[i]]&&h[i-p[i]]<=h[i-p[i]+2])
p[i]++;
if(p[i]+i>mx)
{
mx=p[i]+i;
id=i;
}
}
int ans=0;
for(int i=1;i<=len;i++)
ans=max(ans,p[i]-1);
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
len=0;
h[len]=oo;
for(int i=1;i<=n;i++)
{
h[++len]=-1;
scanf("%d",&h[++len]);
}
h[++len]=-1;
h[++len]=-oo;
printf("%d\n",Manacher());
}
return 0;
}
//hust 1017 舞蹈链
const int oo=0x3f3f3f3f;
//const lld OO=1LL<<61;
const int MOD=10007;
const int maxn=200010;
int h[maxn],n,len;
int p[maxn];
int Manacher()
{
int mx=0,id=0;
for(int i=1;i<=len;i++)
{
if(mx>i)
p[i]=min(mx-i,p[2*id-i]);
else
p[i]=1;
while(h[i+p[i]]==h[i-p[i]]&&h[i-p[i]]<=h[i-p[i]+2])
p[i]++;
if(p[i]+i>mx)
{
mx=p[i]+i;
id=i;
}
}
int ans=0;
for(int i=1;i<=len;i++)
ans=max(ans,p[i]-1);
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
len=0;
h[len]=oo;
for(int i=1;i<=n;i++)
{
h[++len]=-1;
scanf("%d",&h[++len]);
}
h[++len]=-1;
h[++len]=-oo;
printf("%d\n",Manacher());
}
return 0;
}
//多重覆盖hdu2295
//二分答案, 然后使用重复覆盖的Dancing Links模板进行判断,看使用K个能不能覆盖n个点
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 60;
const int MAXM = 60;
const int MAXNODE = MAXN * MAXM;
const double eps = 1e-10;
int K;
struct DLX
{
int n,m,sz;
int U[MAXNODE],D[MAXNODE],R[MAXNODE],L[MAXNODE],Row[MAXNODE],Col[MAXNODE];
int H[MAXN],S[MAXM];
int ands,ans[MAXN];
void init(int _n,int _m)
{
n = _n;
m = _m;
for(int i = 0;i <= m;i++)
{
S[i] = 0;
U[i] = D[i] = i;
L[i] = i-1;
R[i] = i+1;
}
R[m] = 0; L[0] = m;
sz = m;
for(int i = 1 ; i <= n ; i++)
H[i] = -1;
}
void Link(int r,int c)
{
++S[Col[++sz] = c];
Row[sz] = r;
D[sz] = D[c];
U[D[c]] = sz;
U[sz] = c;
D[c] = sz;
if(H[r] < 0)H[r] = L[sz] = R[sz] = sz;
else
{
R[sz] = R[H[r]];
L[R[H[r]]] = sz;
L[sz] = H[r];
R[H[r]] = sz;
}
}
void Remove(int c)
{
for(int i = D[c] ; i != c ; i = D[i])
L[R[i]] = L[i], R[L[i]] = R[i];
}
void resume(int c)
{
for(int i = U[c] ; i != c ; i = U[i])
L[R[i]] = R[L[i]] = i;
}
bool v[MAXNODE];
int f()
{
int ret = 0;
for(int c = R[0] ; c != 0 ; c = R[c])v[c] = true;
for(int c = R[0] ; c != 0 ; c = R[c])
if(v[c])
{
ret++;
v[c] = false;
for(int i = D[c] ;i != c ;i = D[i])
for(int j = R[i] ;j != i ; j = R[j])
v[Col[j]] = false;
}
return ret;
}
bool Dance(int d)
{
if(d + f() > K)return false;
if(R[0] == 0)return d <= K;
int c = R[0];
for(int i = R[0];i != 0;i = R[i])
if(S[i] < S[c])
c = i;
for(int i = D[c];i != c;i = D[i])
{
Remove(i);
for(int j = R[i] ; j != i ; j = R[j])Remove(j);
if(Dance(d + 1))return true;
for(int j = L[i] ; j != i ; j = L[j])resume(j);
resume(i);
}
return false;
}
};
DLX slover;
struct point
{
int x,y;
}city[MAXN],station[MAXN];
inline double dis(point a,point b)
{
return sqrt(1.0 * (a.x - b.x) * (a.x - b.x) + 1.0 * (a.y - b.y) * (a.y - b.y));
}
int main()
{
int T;
scanf("%d",&T);
while (T--)
{
int n,m;
scanf("%d%d%d",&n,&m,&K);
for (int i = 0 ; i < n ; i++)scanf("%d%d",&city[i].x,&city[i].y);
for (int i = 0 ; i < m ; i++)scanf("%d%d",&station[i].x,&station[i].y);
double l = 0,r = 1e8;
while (r - l > eps)
{
double mid = l + (r - l) / 2;
slover.init(m,n);
for (int i = 0 ; i < m ; i++)
{
for (int j = 0 ; j < n ; j++)
{
double dist = dis(station[i],city[j]);
if (dist < mid - eps)
slover.Link(i + 1,j + 1);
}
}
if (slover.Dance(0)) r = mid - eps;
else l = mid + eps;
}
printf("%.6lf\n",l);
}
return 0;
}
//FZU 1686 神龙的难题
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 250;
const int MAXM = 250;
const int MAXNODE = MAXN * MAXN;
const int INF = 0x3f3f3f3f;
struct DLX
{
int n,m,sz;
int U[MAXNODE],D[MAXNODE],R[MAXNODE],L[MAXNODE],Row[MAXNODE],Col[MAXNODE];
int H[MAXN],S[MAXM];
int ansd,ans[MAXN];
void init(int _n,int _m)
{
n = _n;
m = _m;
for(int i = 0;i <= m;i++)
{
S[i] = 0;
U[i] = D[i] = i;
L[i] = i-1;
R[i] = i+1;
}
R[m] = 0; L[0] = m;
sz = m;
for(int i = 1 ; i <= n ; i++)
H[i] = -1;
}
void Link(int r,int c)
{
++S[Col[++sz] = c];
Row[sz] = r;
D[sz] = D[c];
U[D[c]] = sz;
U[sz] = c;
D[c] = sz;
if(H[r] < 0)H[r] = L[sz] = R[sz] = sz;
else
{
R[sz] = R[H[r]];
L[R[H[r]]] = sz;
L[sz] = H[r];
R[H[r]] = sz;
}
}
void Remove(int c)
{
for(int i = D[c] ; i != c ; i = D[i])
L[R[i]] = L[i], R[L[i]] = R[i];
}
void resume(int c)
{
for(int i = U[c] ; i != c ; i = U[i])
L[R[i]] = R[L[i]] = i;
}
bool v[MAXNODE];
int f()
{
int ret = 0;
for(int c = R[0] ; c != 0 ; c = R[c])v[c] = true;
for(int c = R[0] ; c != 0 ; c = R[c])
if(v[c])
{
ret++;
v[c] = false;
for(int i = D[c] ;i != c ;i = D[i])
for(int j = R[i] ;j != i ; j = R[j])
v[Col[j]] = false;
}
return ret;
}
void Dance(int d)
{
if(d + f() >= ansd)return;
if(R[0] == 0)
{
ansd = min(ansd,d);
return;
}
int c = R[0];
for(int i = R[0];i != 0;i = R[i])
if(S[i] < S[c])
c = i;
for(int i = D[c];i != c;i = D[i])
{
Remove(i);
for(int j = R[i] ; j != i ; j = R[j])Remove(j);
Dance(d + 1);
for(int j = L[i] ; j != i ; j = L[j])resume(j);
resume(i);
}
return;
}
};
int id[30][30];
int N,M;
int ln,lm;
DLX slover;
int main()
{
while (scanf("%d%d",&N,&M) != EOF)
{
int cas = 0;
memset(id,0,sizeof(id));
for (int i = 1 ; i <= N ; i++)
{
for (int j = 1 ; j <= M ; j++)
{
int x;
scanf("%d",&x);
if (x) id[i][j] = ++cas;
}
}
scanf("%d%d",&ln,&lm);
slover.init(N * M,cas);
cas = 1;
for (int i = 1 ; i <= N ; i++)
{
for (int j = 1 ; j <= M ; j++)
{
for (int stepx = 0 ; stepx < ln && i + stepx <= N ; stepx++)
for (int stepy = 0 ; stepy < lm && j + stepy <= M ; stepy++)
{
if (id[i + stepx][j + stepy])
slover.Link(cas,id[i + stepx][j + stepy]);
}
cas++;
}
}
slover.ansd = INF;
slover.Dance(0);
printf("%d\n",slover.ansd);
}
return 0;
}
模板temp1
最新推荐文章于 2023-11-10 20:39:51 发布