常用代码技巧--新手区(不定期更新)
1.结构体的一些使用
以前用结构体,定义函数都是裸的
using namespace std; struct node {int x}; node t;//定义
后来看到各位神犇都是这样装逼的
using namespace std; struct node { int x; node(){}//常定义函数 node(int x):x(x){}//方便定义 }; node t;//常定义 node x=node(tmp);//方便定义
2.链表的使用
以前老师教我们vector大法,从此稀疏图空间再也不用怕.
#include<stdio.h> using namespace std; struct edge { int from; int to; int len; edge(){} edge(int from,int to,int len):from(from),to(to),len(len){} }//参数设定 void insert(int from,int to,int len) { n[from].push_back(edge(from,to,len)); n[to].push_back(edge(from,to,len)); }//插入 for(int i=0;i<n[i].size();i++) {}//使用
后来被一道POJ的LCA题目(Housewife Wind (POJ No.2763))给搞了,从此用上静态链表,时间也不用怕
using namespace std; struct edge { int from; int to; int len; int next; //类似于指针 edge()[} edge(int from,int to,int len,int next):from(from),to(to),len(len),next(next){} }; int cnt; //全局空间位置(指向最后一个被利用的空间) int head[maxn];//每个点所连边的首地址 void insert(int from,int to,int len) { n[++cnt]=edge(from,to,len,head[x]); head[x]=cnt; n[++cnt]=edge(from,to,len,head[y]); head[y]=cnt; //每次都给新的边一个新的空间,并传入之前的首地址作为next指针 //并更改首地址 }
for(int i=head[x];i;i=n[i].next)
{}//使用
3.unique函数的使用(离散化大法,去重大法)
先来介绍一下unique函数
algorithm中的函数,作用是将一个数据结构中指定区间(首地址,尾地址)的所有相邻相同元素都挪到这个结构的后面并返回处理后不重复区间的最后一个位置
例如 a[6]=1 1 3 2 5 2
对于这个数组使用unique(a,a+6);
unique会将1 1这个连续重复排列消除,将后者移到数组末端
2虽然出现了两次,但是不连续出现,所以不做处理
数组变成 1 3 2 5 2 1 并返回最后一个地址,即a+5
看看两种由此得来的简洁方法
1)离散化大法(数组)
#include<algorithm> using namespace std; for(int i=1;i<=N;i++) { hash[i]=a[i]; } sort(hash+1,hash+N+1); int cnt=unique(hash+1,hash+N+1)-hash-1; for(int i=1;i<=N;i++) { a[i]=lower_bound(hash+1,hash+1+cnt,a[i])-hash; }
2)去重大法(vector)
顺便还有删除重复项的功能
#include<algorithm> using namespace std; sort(a.begin(),a.end()); a.erase(unique(a.begin(),a.end()),a.end());
3)去重大法(数组)
#include<algorithm> using namespace std; sort(a,a+N); unique(a,a+N);