T1:
子序列
描述
给定3个字符串,求它们的最长公共子序列。
输入
第一行一个整数n,表示三个字符串的长度
接下来三行,每行是一个长度为n只包含小写字母的字符串。
输出
输出最长公共子序列的长度。
输入样例
4
abac
abbc
cbca
输出样例
2
提示
30% n<=10
100% n<=120
就是LCS 3维。。。,方程还是原来的他。。
T2:dun
【问题描述】
定义两个素数是连续的当且仅当这两个素数之间不存在其他的素数(如 7,11 ,(23,29)。给定��,��,在不超过��的正整数中求能够分解为��个连续的素数的和的最大的那个是多少。
【输入格式】
第一行一个正整数��代表数据组数。
接下来��行每行两个正整数��,��代表一组询问。
【输出格式】
输出共��行,每行一个整数代表答案;如果找不到这样的数,输出−1。
【样例输入】
3
20 2
20 3
20 4
【样例输出】
18
15
17
【样例解释】
╭︿︿︿╮
{/ o o /}
( (oo) )
︶︶︶
【数据规模与约定】
对于20%的数据,1≤��≤100。
对于40%的数据,��=1。
对于60%的数据,所有的询问的��相等。
对于100%的数据,1≤��<2000,1≤��≤106。
打出素数表,然后二分查找就好了。。。
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<string>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
#define INF 0x3f3f3f3f
#define clock CLOCKS_PER_SEC
#define cle(x) memset(x,0,sizeof(x))
#define maxcle(x) memset(x,127,sizeof(x))
#define mincle(x) memset(x,-1,sizeof(x))
#define cop(a,x) memcpy(x,a,sizeof(a))
#define FROP "dun"
#define C(a,b) next_permutation(a,b)
#define LL long long
#define smin(x,tmp) x=min(x,tmp)
#define maxx(x1,x2,x3) max(x1,max(x2,x3))
using namespace std;
const int N=80005,W=1e6;
int ss[N],tot,T,n,k;
bool vis[W+5];
LL sum[N];
void mack_ss()
{
int q=sqrt(W+0.5);
for(int j = 2; j <= q ; j++)
for(int i = j * 2 ; i <= 1e6 ; i+=j)
if(i%j==0&&!vis[i])
vis[i]=true;
vis[2]=false;
vis[1]=true;
for(int i = 1; i <= 1e6;i++)if(!vis[i])
ss[++tot]=i;
for(int i = 1; i <= tot;i++)
sum[i]=sum[i-1]+ss[i];
}
int find(int x){
int l=1,r=tot,ans;
while(l<=r)
{
int mid=(l+r)>>1;
if(ss[mid]>=x)ans=mid,r=mid-1;
else l=mid+1;
}
return ans;
}
int main()
{
freopen(FROP".in","r",stdin);
freopen(FROP".out","w",stdout);
scanf("%d",&T);
mack_ss();
while(T--)
{
scanf("%d%d",&n,&k);
int tmp=n/k;
if(k*tmp!=n)tmp++;
int w=find(tmp);
LL ans=-1;
for(int i = w, j = w+k-1; i >=1&&j>=1;i--,j--)
if(sum[j]-sum[i-1]<=n)
{
ans=sum[j]-sum[i-1];
break;
}
printf(AUTO"\n",ans);
}
return 0;
}
T3:发放粮食
描述
有一个村庄在闹饥荒,善良而土豪的YGH决定给他们发放救济粮,该村庄有 n 户人家,每两户人家之间只有一条路可以互相到达,即这些人家之间形成一棵树。现在 YGH 会以这样的形式给他们发放粮食,选择两户人家,然后对这两个户人家路径上的所有人家都发放一袋种类为 w 的救济粮。在完成一系列发放任务后,YGH 想知道每一户人家收到的粮食中数量最多的是哪一种。
输入
第一行两个数 n,q,其中 n 表示村庄共有几户人家,q 表示 YGH 一共发放了几次粮食。接下来 n-1 行,每行两个数 x y,表示编号为 x 和 y 的两户人家之间连有边。接下来 q 行,每行三个数 x y w,表示 YGH 选择了 x 到 y 的路径,对每户人家发放 1 袋种类为 w 的粮食。
输出
输出 n 行,第 i 行输出编号为 i 的人家收到的粮食中数量最多的种类号,如果有多个数量相同的粮食,输出其中最小的种类号,如果没有收到粮食,输出0
样例输入
[1]
2 4
1 2
1 1 1
1 2 2
2 2 2
2 2 1
[2]
5 3
1 2
3 1
3 4
5 3
2 3 3
1 5 2
3 3 3
样例输出
[1]
1
2
[2]
2
3
3
0
2
提示
对于 40% 的数据 n<=1000,q<=1000,1<=w<=1000
对于 100% 的数据 n<=100000,q<=100000,1<=w<=100000 1<=x,y<=n
是hdu5209原题,,还不会树链剖分,所以就用差分写的过了40
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<string>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
#define INF 0x3f3f3f3f
#define clock CLOCKS_PER_SEC
#define cle(x) memset(x,0,sizeof(x))
#define maxcle(x) memset(x,127,sizeof(x))
#define mincle(x) memset(x,-1,sizeof(x))
#define cop(a,x) memcpy(x,a,sizeof(a))
#define FROP "rice"
#define C(a,b) next_permutation(a,b)
#define LL long long
#define smin(x,tmp) x=min(x,tmp)
#define maxx(x1,x2,x3) max(x1,max(x2,x3))
using namespace std;
const int N=1e5+55;
int readin()
{
int res=0;
char ch=getchar();
while(ch>'9'||ch<'0')ch=getchar();
while(ch>='0'&&ch<='9'){res=res*10+ch-'0';ch=getchar();}
return res;
}
struct ii
{
int to,ne;
ii(int to=0,int ne=0):to(to),ne(ne){ }
}ed[N*2];
struct qq
{
int to,ne;
qq(int to=0,int ne=0):to(to),ne(ne){ }
}que[N*2];
struct aa
{
int x,y,w,lca;
aa(int x=0,int y=0,int w=0):x(x),y(y),w(w){ }
bool operator <(const aa &a)const
{
return w<a.w;
}
}Q[N];
int head[N],fa[N],ufa[N],fir[N],n,q,vis[N];
int chan(int x){if(x%2)return (x+1)/2;return x/2;}
int find_fa(int x){return x==ufa[x]?x:ufa[x]=find_fa(ufa[x]);}
void init()
{
n=readin(),q=readin();
for(int i = 1; i <= n-1; i++)
{
int x=readin(),y=readin();
ed[i*2-1]=ii(y,head[x]);
head[x]=i*2-1;
ed[i*2]=ii(x,head[y]);
head[y]=i*2;
}
for(int i = 1; i <= q; i++)
{
int x=readin(),y=readin(),w=readin();
que[i*2-1]=qq(x,fir[y]);
fir[y]=i*2-1;
que[i*2]=qq(y,fir[x]);
fir[x]=i*2;
Q[i]=aa(x,y,w);
}
}
void tarjian(int u)
{
ufa[u]=u;
vis[u]=true;
for(int i = head[u] ; i ; i =ed[i].ne)
{
int v=ed[i].to;
if(fa[u]==v)continue;
fa[v]=u;
tarjian(v);
ufa[v]=u;
}
for(int i = fir[u] ; i ; i = que[i].ne)
{
int v=que[i].to;
if(!vis[v])continue;
int p=chan(i);
Q[p].lca=find_fa(v);
}
}
int answ[N],ans[N];
int mer[N];
void cal(int x,int w)
{
for(int i = head[x]; i ; i=ed[i].ne)
{
int v=ed[i].to;
if(v==fa[x])continue;
cal(v,w);
mer[x]+=mer[v];
}
if(mer[x]==answ[x])smin(ans[x],w);
else if(mer[x]>answ[x])
{
answ[x]=mer[x];
ans[x]=w;
}
}
void work()
{
sort(Q+1,Q+q+1);
int flag=Q[1].w;
for(int i = 1; i <= q; i++)
{
if(flag!=Q[i].w)
{
cal(1,flag);
flag=Q[i].w;
cle(mer);
}
int x=Q[i].x,y=Q[i].y,lca=Q[i].lca;
mer[x]++,mer[y]++,mer[lca]--;
if(fa[lca])mer[fa[lca]]--;
}
cal(1,flag);
for(int i = 1; i <= n; i++)
printf("%d\n",ans[i]);
}
int main()
{
freopen(FROP".in","r",stdin);
freopen(FROP".out","w",stdout);
init();
tarjian(1);
work();
return 0;
}
/*
13 3
1 2
1 3
2 3
2 5
6 3
7 3
8 4
4 9
8 10
8 11
9 12
9 13
10 5 100
12 6 100
6 7 20
*/
然后又把树链给学了,写了QAQ
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<string>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
#define INF 0x3f3f3f3f
#define clock CLOCKS_PER_SEC
#define cle(x) memset(x,0,sizeof(x))
#define maxcle(x) memset(x,127,sizeof(x))
#define mincle(x) memset(x,-1,sizeof(x))
#define minn(x1,x2,x3) min(x1,min(x2,x3))
#define cop(a,x) memcpy(x,a,sizeof(a))
#define FROP "rice"
#define C(a,b) next_permutation(a,b)
#define LL long long
#define smin(x,tmp) x=min(x,tmp)
using namespace std;
const int N=100010;
struct ii
{
int to,ne;
ii(int to=0,int ne=0):to(to),ne(ne){ }
}ed[N*2];
struct node
{
int l,r;
int val,key;
node(int val=0,int key=0):val(val),key(key){ }
}col[N*4];
#define L(x) x<<1
#define R(x) (x<<1)|1
int fir[N],fa[N],son[N],top[N],tid[N],_tid[N],dep[N],siz[N],Index,n,m;
void dfs1(int u)
{
siz[u]=1;
for(int i =fir[u];i;i=ed[i].ne)
{
int v=ed[i].to;
if(fa[u]==v)continue;
fa[v]=u;
dep[v]=dep[u]+1;
dfs1(v);
siz[u]+=siz[v];
if(siz[v]>siz[son[u]])
son[u]=v;
}
}
void dfs2(int u,int tp)
{
top[u]=tp;
tid[u]=++Index;
_tid[Index]=u;
if(!son[u])return;
dfs2(son[u],tp);
for(int i = fir[u];i;i=ed[i].ne)
{
int v=ed[i].to;
if(fa[u]==v||son[u]==v)continue;
dfs2(v,v);
}
}
#define val(x) col[x].val
#define key(x) col[x].key
#define l(x) col[x].l
#define r(x) col[x].r
void pushup(int u)
{
val(u)=max(col[L(u)].val,col[R(u)].val);
key(u)=val(R(u))>val(L(u))?key(R(u)):key(L(u));
}
void build(int l,int r,int u)
{
l(u)=l,r(u)=r;
if(l==r)
{
key(u)=l;
return;
}
int mid=(l+r)>>1;
build(l,mid,L(u));
build(mid+1,r,R(u));
}
void update(int tr,int pos,int v)
{
if(l(tr)==pos&&pos==r(tr))
{
val(tr)+=v;
return;
}
int mid=( l(tr) + r(tr) )>>1;
if(mid>=pos)update(L(tr),pos,v);
else update(R(tr),pos,v);
pushup(tr);
}
vector<int>opt[N];
void sum(int x,int y,int v)
{
opt[x].push_back(v);
opt[y+1].push_back(-v);
}
void change(int x,int y,int v)
{
int f1=top[x],f2=top[y];
while(f1^f2)
{
if(dep[f1]<dep[f2])swap(f1,f2),swap(x,y);
sum(tid[f1],tid[x],v);
x=fa[f1];
f1=top[x];
}
if(dep[x]>dep[y])swap(x,y);
sum(tid[x],tid[y],v);
}
void init()
{
scanf("%d%d",&n,&m);
for(int i = 1; i <= n-1; i++)
{
int x,y;
scanf("%d%d",&x,&y);
ed[i*2-1]=ii(y,fir[x]);
fir[x]=i*2-1;
ed[i*2]=ii(x,fir[y]);
fir[y]=i*2;
}
dep[1]=1;dfs1(1),dfs2(1,1);
int maxx=0;
for(int i = 1; i <= m; i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
maxx=max(z,maxx);
change(x,y,z);
}
build(1,maxx,1);
}
int ans[N];
void work()
{
for(int i = 1; i<=n; i++)
{
int sz=opt[i].size();
for(int j = 0; j<sz;j++)
{
int tmp=opt[i][j];
if(tmp<0)update(1,-tmp,-1);
else update(1,tmp,1);
}
ans[_tid[i]]=val(1)==0?0:key(1);
}
for(int i = 1; i<= n; i++)
printf("%d\n",ans[i]);
}
int main()
{
freopen(FROP".in","r",stdin);
freopen(FROP".out","w",stdout);
init();
work();
return 0;
}