set/map/rope/bitset用法
Set用法
函数
bst.begin() 返回首元素的迭代器指针
bst.end() 返回尾元素的迭代器指针
bst.insert(key) 插入一个值key
bst.erase(key) 删除地址为key的数
bst.erase(l,r) 删除地址[l,r)的数
bst.size() 目前元素个数
bst.find(key) 返回键值等于key的迭代器指针
bst.count(key) 返回键值等于key的元素的个数
bst.lower_bound(key) 返回键值大于等于key的迭代器指针
bst.upper_bound(key) 返回键值大于key的迭代器指针
程序
#include<cstdio> #include<set> using namespace std; set<int> bst; set<int>::iterator now,l,r,it; int main(){ for(int i=1;i<=10;i++)bst.insert(i); now=bst.find(3); bst.erase(now);//1 2 4 5 6 7 8 9 10 l=bst.lower_bound(5);//5 r=bst.upper_bound(8);//9 bst.erase(l,r);//1 2 4 9 10 printf("%d\n",bst.size());// 5 for(it=bst.begin();it!=bst.end();it++)printf("%d ",*it); }
然后来实战演习,就来做ZJOI2007报表统计吧,实在太SB,懒得手写,现在学了set正好写一发
写是挺容易的,但由于不会MAP,RE了几发,搞了MAP后终于在LJOJ上A了,兴冲冲的去BZOJ上交,没想到TLE了、、
也许是写set姿势不太对,于是加了读入优化,终于卡过了,但似乎是最后一名哈哈
#include<cstdio> #include<set> #include<map> #define N 500010 #define inf 1000000000 using namespace std; int n,m,i,now,key,t,ans,st[N],ed[N]; char s[99]; multiset<int> bst,bst2; map<int,int> w; int abs(int x){if(x<0)return -x;return x;} int min(int x,int y){if(x<y)return x;return y;} void insert(int x){w[x]++;if(w[x]==1)bst.insert(x);} void push(int x){ int l=*--bst2.lower_bound(x),r=*bst2.lower_bound(x); ans=min(ans,min(x-l,r-x)); bst2.insert(x); } int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int main(){ n=read();m=read(); ans=inf; bst2.insert(inf);bst2.insert(-inf); for(i=1;i<=n;i++){ key=read(); push(key); ed[i]=st[i]=key; if(i>1)insert(abs(st[i]-st[i-1])); } now=n; while(m--){ scanf("%s",s); if(s[0]=='I'){ i=read();key=read(); if(i!=n){ t=abs(ed[i]-st[i+1]); w[t]--; if(!w[t])bst.erase(t); } insert(abs(ed[i]-key)); insert(abs(key-st[i+1])); ed[i]=key; push(key); }else if(s[4]=='G')printf("%d\n",*bst.begin()); else printf("%d\n",ans); } }
map用法
map构造函数:
map<int/char/string(原变量),int/char/string(现变量)>mapint/char/string;
map添加数据:
map<int,string>mp;
1.mp.insert(pair<int,string>(233,"orzmxh"));
2.mp.insert(map<int,string>::value_type(521,"orzhzh"));
3.mp[666]="orzhhw";
mp->first第一项 mp->second第二项
map函数:
mp.begin() 返回首元素的迭代器指针
mp.end() 返回尾元素的迭代器指针
mp.size() 目前元素个数
mp.bool() 判断容器是否空,若返回true,表明容器已空
mp.find(key) 返回键值等于key的迭代器指针
mp.count(key) 返回键值等于key的元素的个数
mp.lower_bound(key) 返回键值大于等于key的迭代器指针
mp.upper_bound(key) 返回键值大于key的迭代器指针
mp.erase(key) 删除迭代指针key处元素
mp.erase(l,r) 删除[l,r)之间元素
mp.swap(mp2) 交换mp和mp2映射元素
mp.clear() 删除所有元素
#include<map> #include<cstdio> using namespace std; map<char,int> mp1,mp2; map<char,int>::iterator it; int main(){ mp1['a']=1;mp1['b']=2; mp1['c']=3;mp1['d']=4; mp2.insert(pair<char,int>('e',10)); mp2.insert(pair<char,int>('f',40)); mp2.insert(map<char,int>::value_type('g',60)); mp2.insert(map<char,int>::value_type('h',80)); mp1.swap(mp2); it=mp2.find('b'); printf("%d\n",it->second);//2 mp2.erase(mp2.find('b'),mp2.find('d'));//<a,1> <d,4> printf("%d\n",mp2.size());//2 printf("%d\n",mp1.count('g'));//1 for(it=mp1.begin();it!=mp1.end();it++)//<e,10><f,40> printf("%c %d\n",it->first,it->second);//<g,60><h,80> }
Rope用法
头文件:#include<ext/rope>
声明:using namespace __gnu_cxx;
定义:crope x;
函数:
x.push_back(ch) 在末尾添加字符ch
x.insert(pos,s) 在pos位置插入字符ch
x.erase(pos,x) 从pos位置开始删除x个
x.replace(pos,ch) 将位置为pos的字符换成ch
x.substr(pos,x) 从pos位置开始提取x个字符
x.copy(pos,x,s) 将从pos位置开始x个字符提取到s中
x.at(x)/[x]访问第x个元素
#include<ext/rope> #include<cstdio> using namespace std; using namespace __gnu_cxx; crope x; char s[10000000]; int main(){ x.insert(0,"233"); x.erase(1,1);//23 x.replace(1,"!");//2! x.push_back('1');//2!1 x.insert(2,"&^");//2!&^1 x.copy(0,5,s); printf("%s",s);//2!&^1 }
然后听毛主力说ROPE可以可持久化,只要fa[i]=new rope<int>(*fa[i-1]);就行啦
BZOJ3673&3674可持久化并查集,只有700多B,太爽啦
#include<cstdio> #include<ext/rope> using namespace __gnu_cxx; rope<int> *fa[200002]; int n,m,i,x,y,p,ans,a[200002]; int find(int x){ if(fa[i]->at(x)!=x){ int f=find(fa[i]->at(x)); if(f==fa[i]->at(x))return f; fa[i]->replace(x,f); return fa[i]->at(x); } return x; } void uni(int x,int y){int p=find(x),q=find(y);fa[i]->replace(q,p);} int main(){ scanf("%d%d",&n,&m);for(i=0;i<=n;i++)a[i]=i; fa[0]=new rope<int>(a,a+n+1); for(i=1;i<=m;i++){ fa[i]=new rope<int>(*fa[i-1]);scanf("%d",&p); if(p==1)scanf("%d%d",&x,&y),uni(x^ans,y^ans); else if(p==2)scanf("%d",&x),fa[i]=fa[x^ans]; else if(p==3)scanf("%d%d",&x,&y),printf("%d\n",(ans=find(x^ans)==find(y^ans))); } }
bitset用法
今天打BC被这个坑了,出题人脑子有gin一定要用bitset,不用就超时,也因此失去了38元奖励。。
1.头文件:#include<bitset>
2.定义:bitset<2000000> b(key);//key为初值,但从右向左读
3.函数:b.any() b中是否存在置为1的二进制位
b.none() b中不存在置为1的二进制位吗
b.count() b中置为1的二进制位的个数
b.size() b中二进制位的个数
b[pos] 访问b中在pos处的二进制位
b.test(pos) b中在pos处的二进制位是否为1
b.set() 把b中所有二进制位都置为1
b.set(pos) 把b中在pos处的二进制位置为1
b.reset() 把b中所有二进制位都置为0
b.reset(pos) 把b中在pos处的二进制位置为0
b.flip() 把b中所有二进制位逐位取反
b.flip(pos) 把b中在pos处的二进制位取反
b.to_ulong() 用b中同样的二进制位返回一个unsigned long值
os << b 把b中的位集输出到os流
2023年4月23日 20:14
crediblebh