}
}
4、常用函数
copy、copy_if:copy直接拷贝,比for循环高效,最坏为线性复杂度,而且这个可以说是一个copy族函数,还有类似的满足一定条件的copy_if等。
find、find_i:查找第一个匹配的值或第一个满足函数使其为true的值位置,没有返回指定区间的末尾,线性复杂度,还有一些不怎么常用的find族函数就不多介绍了。
count、count_if:返回匹配或使函数为true的值的个数,线性复杂度。
search:这是寻找序列是否存在于另一个序列中的函数,挺好用的,某些简单的寻找公共子串的题就可以这样写,时间复杂度二次。
reverse:翻转一个区间的值,我经常遇到需要这种题,直接reverse了,不需要for循环了,主要是方便。
for_each:直接对一个区间内的每个元素执行后面的函数操作,写起来简单。
max、min、max_element、min_element:寻找两个数或者一个区间的最大最小值,都可以添加比较函数参数。
集合操作函数:includes、set_union、set_difference、set_intersection、set_symmetric_difference、前面这些函数的最差复杂度为线性,另外附加一个序列的操作函数merge,相当于归并排序中的合并函数,时间复杂度为线性,注意这些函数的操作对象都必须是升序的。
例:
#include
#include
using namespace std;
void out(int a) { if (a != -1) printf("%d ",a); }
int main() {
int a[5] = {1, 8, 10, 52, 100};
int b[5] = {6, 8, 9, 10, 1000};
int c[20];
printf("a集合为:");
for_each(a, a+5, out);
puts("");
printf("b集合为:");
for_each(b, b+5, out);
puts("");
//判断b是否是a的子集。
if(includes(a, a+5, b, b+5)) printf("bis a sub set of a\n");
//合并两个有序序列,必须为合并后的序列分配空间,否则程序会崩溃。
printf("两个集合的合并序列为:");
merge(a, a+5, b, b+5, c);
for_each(c, c+10, out);
puts("");
//求两个集合的并集。
fill(c, c+20, -1);
set_union(a, a+5, b, b+5, c);
printf("两个集合的并集为:");
for_each(c, c+10, out);
puts("");
//求两个集合的交集。
fill(c, c+20, -1);
set_intersection(a, a+5, b, b+5, c);
printf("两个集合的交集为:");
for_each(c, c+10, out);
puts("");
//求两个集合的差集,这里为a-b。
fill(c, c+20, -1);
set_difference(a, a+5, b, b+5, c);
printf("a-b的差集为:");
for_each(c, c+10, out);
puts("");
//求两个集合的差集,这里为b-a。
fill(c, c+20, -1);
set_difference(b, b+5, a, a+5, c);
printf("b-a的差集为:");
for_each(c, c+10, out);
puts("");
//求两个集合的对称差
set_symmetric_difference(a, a+5, b, b+5,c);
printf("两个集合的对称差为:");
for_each(c, c+10, out);
puts("");
return 0;
}
树结构模板
1、树状数组
例:HDU 1166
#include
#include
const intMAX = 50010 * 4;
intsegment[MAX];
voidpushUp(int root)
{
segment[root] = segment[root * 2] + segment[root* 2 + 1];
}
voidbuildTree(int root, int left, int right)
{
if(left == right)
{
scanf("%d",&segment[root]);
return;
}
int mid = (left + right) / 2;
buildTree(root * 2, left, mid);
buildTree(root * 2 + 1, mid + 1, right);
pushUp(root);
}
voidupdate(int root, int pos, int add_num, int left, int right)
{
if (left == right)
{
segment[root] += add_num;
return;
}
int mid = (left + right) / 2;
if (pos <= mid)
update(root * 2, pos, add_num, left,mid);
else
update(root * 2 + 1, pos, add_num, mid+ 1, right);
pushUp(root);
}
intgetSum(int root, int left, int right, int L, int R)
{
if(left == L && right == R)
{
return segment[root];
}
int mid = (L + R) / 2;
int res = 0;
if(left > mid)
{
res += getSum(root * 2 + 1, left,right, mid + 1, R);
}
else if(right <= mid)
{
res += getSum(root * 2, left, right, L,mid);
}
else
{
res += getSum(root * 2, left, mid, L,mid);
res += getSum(root * 2 + 1, mid + 1,right, mid + 1, R);
}
return res;
}
int main()
{
int T;
scanf("%d", &T);
for(int kase = 1; kase <= T; kase++)
{
int n;
scanf("%d", &n);
buildTree(1, 1, n);
char op[10];
int t1, t2;
printf("Case %d:\n", kase);
while(scanf("%s", op))
{
if(op[0] == 'E')
break;
scanf("%d %d", &t1,&t2);
if(op[0] == 'A')
{
update(1, t1, t2, 1, n);
}
else if(op[0] == 'S')
{
update(1, t1, -t2, 1, n);
}
else
{
printf("%d\n",getSum(1, t1, t2, 1, n));
}
}
}
return 0;
}
2、后缀树
例:CodeForces 128B
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#pragma comment(linker, "/STACK:1024000000,1024000000")
template
bool scanff(T &ret){ //Faster Input
char c; int sgn; T bit=0.1;
if(c=getchar(),c==EOF) return 0;
while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar();
sgn=(c=='-')?-1:1;
ret=(c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
if(c==' '||c=='\n'){ ret*=sgn; return 1; }
while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10;
ret*=sgn;
return 1;
}
#define inf 1073741823
#define llinf 4611686018427387903LL
#define PI acos(-1.0)
#define lth (th<<1)
#define rth (th<<1|1)
#define rep(i,a,b) for(int i=int(a);i<=int(b);i++)
#define drep(i,a,b) for(int i=int(a);i>=int(b);i--)
#define gson(i,root) for(int i=ptx[root];~i;i=ed[i].next)
#define tdata int testnum;scanff(testnum);for(int cas=1;cas<=testnum;cas++)
#define mem(x,val) memset(x,val,sizeof(x))
#define mkp(a,b) make_pair(a,b)
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define pb(x) push_back(x)
using namespace std;
typedef long long ll;
typedef pair pii;
#define SIZE 27
struct suffixtree{
struct node{
int l,r,point,a[SIZE];
void init(){
mem(a,0);
point=l=0;
r=-1;
}
}T[400011];
char s[400011];
int actnode,actride,actline;
int rest,total,temp,linker,len;
void builtleaf(int root,int line){
total++;
T[total].init();
T[total].l=len;
T[total].r=100000001;
T[root].a[line]=total;
rest--;
}
bool pd_ride(int next){
temp=T[next].r-T[next].l+1;
if(actride>=temp){
actride-=temp;
actnode=next;
actline+=temp;
return true;
}
return false;
}
void link(int x){
if(linker>0)T[linker].point=x;
linker=x;
}
void insert(int wait){
s[++len]=wait;
rest++;
linker=0;
while(rest>0){
if(actride==0)actline=len;
if(T[actnode].a[s[actline]]==0){
builtleaf(actnode,s[actline]);
link(actnode);
}
else{
int next=T[actnode].a[s[actline]];
if(pd_ride(next))continue;
if(s[T[next].l+actride]==wait){
actride++;
link(actnode);
break;
}
total++;
T[total].init();
T[actnode].a[s[actline]]=total;
T[total].l=T[next].l;
T[total].r=T[next].l+actride-1;
T[next].l+=actride;
T[total].a[s[T[next].l]]=next;
link(total);
builtleaf(total,wait);
}
if(actnode==0&&actride>0){
actride--;
actline=len-rest+1;
}
else actnode=T[actnode].point;
}
}
void clear(){
total=0;
len=0;
T[0].init();
actnode=actride=actline=0;
}
void debug(){
rep(i,0,total){
printf("T[%d] (%d %d)\n",i,T[i].l,T[i].r);
}
}
}st;
#define NN 400400
char s[NN];
ll cot[NN];
ll sum;
ll k;
int len;
ll getcot(int x){
ll temp=0;
ll bj=1;
rep(i,0,26){
if(st.T[x].a[i]){
bj=0;
temp+=getcot(st.T[x].a[i]);
}
}
cot[x]=temp+bj;
return cot[x];
}
ll edr,edx;
int alen=0;
char ans[NN];
void dfs(int x){
sum+=(ll)(min(st.T[x].r,len)-st.T[x].l+1)*cot[x];
if(sum>=k){
edx=x;
edr=min(ll(st.T[x].r),ll(len));
while(sum-cot[x]>=k){
sum-=cot[x];
edr--;
}
//printf("%lld %lld\n",edx,edr);
//return;
}
rep(i,0,26){
if(st.T[x].a[i]&&sum
dfs(st.T[x].a[i]);
}
}
if(sum>=k){
drep(i,min(edr,ll(st.T[x].r)),st.T[x].l){
ans[alen++]=s[i];
}
}
}
main(){
st.clear();
scanf("%s",s+1);
len=strlen(s+1);
rep(i,1,len)st.insert(s[i]-'a');
st.insert(26);
scanf("%lld",&k);
if(ll(len)*ll(len+1)/2LL
printf("No such line.\n");
return 0;
}
getcot(0);
dfs(0);
ans[alen]=0;
reverse(ans,ans+alen);
printf("%s\n",ans);
}
3、线段树
例:HDU 1542
#include
#include
#include
#include
usingnamespace std;
constint SIZE=505;
intadd[SIZE<<2];
doublex[SIZE<<2],sum[SIZE<<2];
structnode{
int ss;
double l,r,h;
node(){}
node(double a,double b,double c,intd):l(a),r(b),h(c),ss(d){}
friend bool operator<(node p,node q){
return p.h
}
}s[SIZE];
voidpushup(int rt,int l,int r){
if(add[rt])
sum[rt]=x[r+1]-x[l];
else if(l==r)
sum[rt]=0;
else
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
voidupdate(int L,int R,int c,int l,int r,int rt){
int m;
if(L<=l&&r<=R){
add[rt]+=c;
pushup(rt,l,r);
return;
}
m=(l+r)>>1;
if(L<=m)
update(L,R,c,l,m,rt<<1);
if(R>m)
update(L,R,c,m+1,r,rt<<1|1);
pushup(rt,l,r);
}
intmain(){
int n,i,k,l,m,r,cas;
double a,b,c,d,ans;
cas=1;
while(scanf("%d",&n)!=EOF&&n){
k=1,ans=m=0;
for(i=0;i
scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
x[m]=a;
s[m++]=node(a,c,b,1);
x[m]=c;
s[m++]=node(a,c,d,-1);
}
sort(x,x+m);
sort(s,s+m);
for(i=1;i
if(x[i]!=x[i-1])
x[k++]=x[i];
memset(add,0,sizeof(add));
memset(sum,0,sizeof(sum));
for(i=0;i
l=lower_bound(x,x+k,s[i].l)-x;
r=lower_bound(x,x+k,s[i].r)-x-1;
update(l,r,s[i].ss,0,k-1,1);
ans+=(sum[1]*(s[i+1].h-s[i].h));
}
printf("Test case #%d\nTotalexplored area: %.2lf\n\n",cas++,ans);
}
return 0;
}
4、并查集
例:POJ 2492
#include
#define N 2002
int fa[N],rank[N],resex[N];
void init(int len)
{
int i;
for(i=1;i<=len;i++)
{
fa[i]=i;
rank[i]=0;
resex[i]=0;
}
}
int find(int x)
{
if(fa[x]!=x)
{
fa[x]=find(fa[x]);//路径压缩
}
return fa[x];
}
void Union(int a,int b)
{
int x=find(a);
int y=find(b);
if(rank[x]>rank[y])//按秩合并
fa[y]=x;
else
{
fa[x]=y;
if(rank[x]==rank[y])
rank[y]++;
}
}
int main()
{
int T,n,m,i,a,b,num=0,flag;
scanf("%d",&T);
while(num
{
flag=1;
num++;
scanf("%d%d",&n,&m);
init(n);
for(i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
if(!flag)continue;
int x=find(a);
int y=find(b);
if(x==y)flag=0;
if(resex[a]!=0)Union(resex[a],b);
else resex[a]=b;
if(resex[b]!=0)Union(resex[b],a);
else resex[b]=a;
}
printf("Scenario#%d:\n",num);
if(!flag)
printf("Suspiciousbugs found!\n\n");
else
printf("Nosuspicious bugs found!\n\n");
}
return 0;
}