这是一个句子测试

12
1
2015
0

Contest20151130滚粗记

听说这是JSOI2015Day2

膜了贵省的题目,感到不明觉厉。

Orz NiroBC 230

Orz Gold_7 220

Orz Chrysanthemum 220

我等蒟蒻第三题炸飞,120收场。

T1

第一眼看到题目慌掉了。让我打个暴力压压惊。

好像答案就是2nk。。。。

T2

第一眼看到题目慌掉了。让我打个暴力压压惊。

诶这个K究竟有什么用,不明觉厉啊。那就20分好了。

正解是:

二分答案(什么居然是分数规划)

那么如果存在更优解,显然有:[tex]\frac{M(i,j)-m(i,j)}{j-i+K}>b[/tex]

首先暴力处理出len=l的情况。

显然对于len(l,r],如果它能产生最优解,那么可以得到:

M(i,j)=a[i],m(i,j)=a[j]或M(i,j)=a[j],m(i,j)=a[i]。

那么将分母乘过去,就有:a[i]+b*i-(a[j]+b*j)>b*K或a[i]-b*i-(a[j]-b*j)>b*K。

令c[i]=a[i]+b*i或a[i]-b*i,那么等式成立的条件是:

存在i,j,满足:l<j-i+1<=r,c[i]-c[j]>b*K。

那么就可以单调队列辣!!!

T3

第一眼看到题目慌掉了,突然发现这道题好像做过类似的。

恩好像跟前面那个Count on a tree差不多,写个可持久化trie树吧。

恩我第一次写。

恩我过样例了。

恩我炸了。

原来是lca的时候大于小于号打错了。

(听说这道题还有一个不明觉厉的hash做法)

Codes

#include<cstdio>
#include<algorithm>
#include<cstring>
typedef long long ll;
using namespace std;
const int maxn=1000000007;
ll n,k;
ll quickmi(ll x,ll y,ll mod){
	ll ans=1;
	while (y){
		if ((y&1)==1)ans=ans*x%mod;
		x=x*x%mod;
		y=y>>1;
	}
	return ans;
}
int main(){
	freopen("subset.in","r",stdin);
	freopen("subset.out","w",stdout);
	scanf("%lld%lld",&n,&k);
	printf("%lld\n",quickmi(2,n*k,maxn));
}
#include<cstdio>
#include<algorithm>
#include<cstring>
typedef long long ll;
using namespace std;
const int M=100010;
double a[M],c[M];
int cas,n,K,l,r,i;
struct node{int head;int tail;int w[M];}h1,h2;
int check(double b){
	for (int i=1;i<=n;i++)c[i]=a[i]+b*i;
	h1.head=1,h1.tail=1,h1.w[1]=n;
	for (int i=n-l+1;i>=1;i--){
		while (h1.head<h1.tail&&h1.w[h1.head]>i+r-1)h1.head++;
		if (c[i]-c[h1.w[h1.head]]>=b*K)return 1;
		while (h1.head<=h1.tail&&c[h1.w[h1.tail]]>=c[i+l-2])h1.tail--;
		h1.w[++h1.tail]=i+l-2;
	}
	for (int i=1;i<=n;i++)c[i]=-a[i]+b*i;
	h1.head=1,h1.tail=1,h1.w[1]=n;
	for (int i=n-l+1;i>=1;i--){
		while (h1.head<h1.tail&&h1.w[h1.head]>i+r-1)h1.head++;
		if (c[i]-c[h1.w[h1.head]]>=b*K)return 1;
		while (h1.head<=h1.tail&&c[h1.w[h1.tail]]>=c[i+l-2])h1.tail--;
		h1.w[++h1.tail]=i+l-2;
	}
	return 0;
}
int main(){
	scanf("%lld",&cas);
	while (cas--){
		scanf("%d%d%d%d",&n,&K,&l,&r);
		for (i=1;i<=n;i++)scanf("%lf",&a[i]);
		double L=0,R=1000;
		h1.head=1,h1.tail=1,h2.head=1,h2.tail=1;
		h1.w[1]=1,h2.w[1]=1;
		for (i=2;i<=n;i++){
			while (h1.head<h1.tail&&h1.w[h1.head]<i-l+1)h1.head++;
			while (h2.head<h2.tail&&h2.w[h2.head]<i-l+1)h2.head++;
			while (h1.head<=h1.tail&&a[h1.w[h1.tail]]<a[i])h1.tail--;
			while (h2.head<=h2.tail&&a[h2.w[h2.tail]]>a[i])h2.tail--;
			h1.w[++h1.tail]=i;
			h2.w[++h2.tail]=i;
			if (i>=l)L=max(L,(a[h1.w[h1.head]]-a[h2.w[h2.head]])/(l-1+K));
		}
		l++;
		if (l<=r){
			while (R-L>0.000001){
				double mid=(L+R)/2;
				if (check(mid))L=mid;else R=mid;
			}
		}
		printf("%.4lf\n",L);
	}
}
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int M=200010;
int n,i,x,y,m,edgenum,cnt;
char a[M];
int head[M],vet[M],next[M],root[M],dep[M];
int fa[M][17];
char ch[M][20];
char st[20];
struct node{int w;int son[26];}tree[M*10];
void addedge(int x,int y){
	vet[++edgenum]=y;
	next[edgenum]=head[x];
	head[x]=edgenum;
}
void addtrie(int &p,int x,int dep){
	tree[++cnt]=tree[p],p=cnt,tree[p].w++;
	if (dep==strlen(ch[x]))return;
	addtrie(tree[p].son[ch[x][dep]-'a'],x,dep+1);
}
int query(int x,int dep){
	if (x==0&&dep)return 0;
	if (dep==strlen(st))return tree[x].w;
	return query(tree[x].son[st[dep]-'a'],dep+1);
}
int lca(int x,int y){
	if (dep[x]<dep[y])swap(x,y);
	int t=dep[x]-dep[y];
	for (int i=0;i<=16;i++)
		if (t&(1<<i))x=fa[x][i];
	for (int i=16;i>=0;i--)
		if (fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
	if (x==y)return x;
	return fa[x][0];
}
void dfs(int u,int cnt){
	int e,v;
	if (u!=1)root[u]=root[fa[u][0]],addtrie(root[u],cnt,0);
	for (int i=1;i<=16;i++)
		if ((1<<i)<=dep[u])fa[u][i]=fa[fa[u][i-1]][i-1];
			else break;
	for (e=head[u];e;e=next[e]){
		v=vet[e];
		if (v!=fa[u][0])fa[v][0]=u,dep[v]=dep[u]+1,dfs(v,e+1>>1);
	}
}
int main(){
	scanf("%d",&n);
	for (i=1;i<n;i++){
		scanf("%d%d",&x,&y);
		scanf("%s",ch[i]);
		addedge(x,y);
		addedge(y,x);
	}
	dfs(1,-1);
	scanf("%d",&m);
	for (i=1;i<=m;i++){
		scanf("%d%d",&x,&y);
		scanf("%s",st);
		printf("%d\n",query(root[x],0)+query(root[y],0)-2*query(root[lca(x,y)],0));
	}
}

 

Category: 蒟蒻的滚粗记 | Tags: | Read Count: 154

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com