string 操作:
1 =,assign() //赋以新值 2 s.assign(str); 3 s.assign(str,1,3);//如果str是”iamangel” 就是把”ama”赋给字符串 4 s.assign(str,2,string::npos);//把字符串str从索引值2开始到结尾赋给s 5 s.assign(“gaint”); 6 s.assign(“nico”,5);//把’n’ ‘i’ ‘c’ ‘o’ ‘’赋给字符串 7 s.assign(5,’x’);//把五个x赋给字符串 8 b) swap() //交换两个字符串的内容 9 c) +=,append(),push_back() //在尾部添加字符 10 d) insert() //插入字符 11 e) erase() //删除字符 12 g) replace() //替换字符 13 h) +//串联字符串 14 ==,!=,<,<=,>,>=,compare() //比较字符串 15 string s(“abcd”); 16 s.compare(“abcd”); //返回0 17 s.compare(“dcba”); //返回一个小于0的值 18 s.compare(“ab”); //返回大于0的值 19 s.compare(s); //相等 20 s.compare(0,2,s,2,2); //用”ab”和”cd”进行比较 小于零 21 s.compare(1,2,”bcx”,2); //用”bc”和”bc”比较。 22 j) size(),length() //返回字符数量 23 r) copy() //将某值赋值为一个c_string 24 s) c_str() //将内容以c_string返回 25 u) substr() //返回某个子字符串 26 s.substr(11);//从索引11往后的子串 27 s.substr(5,6);//从索引5开始6个字符 28 k)find() 29 string::size_type position; 30 position = s.find("xx"); 31 //查找s 中flag 出现的所有位置。 32 flag="a"; 33 position=0; 34 while((position=s.find_first_of(flag,position))!=string::npos) 35 { 36 //position=s.find_first_of(flag,position); 37 cout<<"position : "<<position<<endl; 38 position++; 39 }
gcd :
int gcd(int x,int y){ return y?gcd(y,x%y):x; }
lcm :
int lcm(int a,int b) {return a*b/gcd(a,b); }
扩展欧几里得 :
1 int exgcd(int a, int b, int& x, int& y){//a*x+b*y=gcd(a,b)=d;(x,y)为其一组整数解 2 int d = a; 3 if(b != 0){ 4 d = exgcd(b, a % b, y, x); 5 y -= (a / b) * x; 6 }else { 7 x = 1; 8 y = 0; 9 } 10 return d; 11 }
快速幂 :
1 ll quick_power(ll base, ll n){ 2 ll res = 1; 3 while (n > 0){ 4 if (n & 1) 5 res *= base; // res = (res * base) % mod; 6 base *= base; //base = (base * base) % mod; 7 n >>= 1; 8 } 9 return res; 10 }
矩阵快速幂 :
1 int mod; 2 int n,m,sum; 3 struct mtix{ 4 int a[maxn][maxn]; 5 mtix(){memset(a,0,sizeof(a));} 6 }f; 7 mtix mul(mtix a,mtix b){ 8 mtix c; 9 for (int i=1;i<=n;i++) 10 for (int j=1;j<=n;j++) 11 for (int k=1;k<=n;k++) 12 {c.a[i][j]+=(a.a[i][k]*b.a[k][j])%mod;c.a[i][j]%=mod;} 13 return c; 14 } 15 mtix mpow(int y){ 16 mtix ans; 17 mtix tem=f; 18 for (int i=1;i<=n;i++) 19 ans.a[i][i]=1; 20 for (;y;tem=mul(tem,tem),y>>=1) 21 if (y&1) ans=mul(ans,tem); 22 for (int i=1;i<=n;i++) 23 sum+=ans.a[i][i]; 24 cout<<sum%mod<<endl; 25 return ans; 26 } 27 int main(){ 28 cin>>n>>m; 29 for (int i=1;i<=n;i++) 30 for (int k=1;k<=n;k++) 31 cin>>f.a[i][k]; 32 mpow(m); 33 }
最长公共子序列lcs :
1 char a[1010],b[1010]; 2 int dp[1010][1010]; 3 int main(){ 4 int lena,lenb,i,j; 5 while(scanf("%s%s",&a,&b)!=eof){ 6 lena=strlen(a); 7 lenb=strlen(b); 8 memset(dp,0,sizeof(dp)); 9 for(i=1;i<=lena;++i){ 10 for(j=1;j<=lenb;++j){ 11 if(a[i-1]==b[j-1]) 12 dp[i][j]=dp[i-1][j-1]+1; 13 else 14 dp[i][j]=max(dp[i-1][j],dp[i][j-1]); 15 } 16 } 17 printf("%dn",dp[lena][lenb]); 18 } 19 return 0; 20 }
最短路floyd :
1 for (int k = 1; k <= n; k++) { 2 for (int i = 1; i <= n; i++) { 3 if (i == k) continue; 4 for (int j = 1; j <= n; j++) { 5 if (i == j || k == j) continue; 6 dis[i][j] = min(dis[i][j], dis[i][k]+ dis[k][j]); 7 } 8 } 9 }
并查集 :
1 int pre[maxn]; 2 int tot[maxn];//集合元素数量 3 int rank[maxn];//集合排名 4 int n,m,k; 5 void init(){ 6 for(int i=1;i<=n;++i){ 7 pre[i]=i; 8 tot[i]=1; 9 } 10 mst(rank,0); 11 } 12 int find(int x){ 13 if(x==pre[x]) 14 return x; 15 else 16 return pre[x]=find(pre[x]); 17 } 18 19 void join(int x, int y){ 20 x = find(x); 21 y = find(y); 22 if (rank[x] > rank[y]){ 23 pre[y] = x; 24 if (x != y) 25 tot[x] += tot[y]; 26 } 27 else{ 28 pre[x] = y; 29 if (x != y) 30 tot[y] += tot[x]; 31 if (rank[x] == rank[y]) 32 rank[y] += 1; 33 } 34 }
sg 打表 :
//f[]:可以取走的石子个数 //sg[]:0~n的sg函数值 int f[maxn],sg[maxn],mex[maxn]; void getsg(int n){ int i,j; memset(sg,0,sizeof(sg)); for(i=1;i<=n;i++){ memset(mex,0,sizeof(mex)); for(j=1;f[j]<=i&&f[j]<=m;j++) //注意加f[i]的限定条件,此处为f[j]<=m mex[sg[i-f[j]]]=1; for(j=0;j<=n;j++){ //求mex中未出现的最小的非负整数 if(mex[j]==0){ sg[i]=j; break; } } //cout<<i<<" "<<sg[i]<<endl; } }
1 int f[maxn],sg[maxn];bool mex[maxn]; 2 void getsg(int k,int n){ 3 int i,j; 4 memset(sg,0,sizeof(sg)); 5 for(i=1;i<=n;i++){ 6 memset(mex,0,sizeof(mex)); 7 for(j=1;f[j]<=i&&j<=k;j++) 8 mex[sg[i-f[j]]]=true; 9 for(j=0;j<=n;j++){ 10 if(mex[j]==false){ 11 sg[i]=j; 12 break; 13 } 14 } 15 } 16 }//这个好像更快
sg_dfs :
1 1 //注意 s数组要按从小到大排序 sg函数要初始化为-1 对于每个集合只需初始化1遍 2 2 //n是集合s的大小 s[i]是定义的特殊取法规则的数组 3 3 int s[110],sg[10010],n; 4 4 int sg_dfs(int x) 5 5 { 6 6 int i; 7 7 if(sg[x]!=-1) 8 8 return sg[x]; 9 9 bool mex[110]; 10 10 memset(mex,0,sizeof(mex)); 11 11 for(i=0;i<n;i++) 12 12 { 13 13 if(x>=s[i]) 14 14 { 15 15 sg_dfs(x-s[i]); 16 16 mex[sg[x-s[i]]]=1; 17 17 } 18 18 } 19 19 int e; 20 20 for(i=0;;i++) 21 21 if(!mex[i]) 22 22 { 23 23 e=i; 24 24 break; 25 25 } 26 26 return sg[x]=e; 27 27 }
线段树 :
1 //求和为例建树 2 1 const int maxm=50000; //定义 maxm 为线段最大长度 3 2 4 3 int a[maxm+5],st[(maxm<<2)+5]; // a 数组为 main 函数中读入的内容,st 数组为需要查询的数的信息(如和、最值等),树的空间大小为线段最大长度的四倍 5 4 6 5 void build(int o,int l,int r){ //传入的参数为 o:当前需要建立的结点;l:当前需要建立的左端点;r:当前需要建立的右端点 7 6 if(l==r)st[o]=a[l]; //当左端点等于右端点即建立叶子结点时,直接给数组信息赋值 8 7 else{ 9 8 int m=l+((r-l)>>1); // m 为中间点,左儿子结点为 [l,m] ,右儿子结点为 [m+1,r]; 10 9 build(o<<1,l,m); //构建左儿子结点 11 10 build((o<<1)|1,m+1,r); //构建右儿子结点 12 11 st[o]=st[o<<1]+st[(o<<1)|1]; //递归返回时用儿子结点更新父节点,此处可进行更新最大值、最小值、区间和等操作 13 12 } 14 13 } 15 14 16 15 { //在 main 函数中的语句 17 16 build(1,1,n); 18 17 }
1 //单点修改 2 void update(int o,int l,int r,int ind,int ans){ //o、l、r为当前更新到的结点、左右端点,ind为需要修改的叶子结点左端点,ans为需要修改成的值; 3 if(l==r){ //若当前更新点的左右端点相等即到叶子结点时,直接更新信息并返回 4 st[o]=ans; 5 return; 6 } 7 int m=l+((r-l)>>1); 8 if(ind<=m){ //若需要更新的叶子结点在当前结点的左儿子结点的范围内,则递归更新左儿子结点,否则更新右儿子结点 9 update(o<<1,l,m,ind,ans); 10 } 11 else{ 12 update((o<<1)|1,m+1,r,ind,ans); 13 } 14 st[o]=max(st[o<<1],st[(o<<1)|1]);//递归回之后用儿子结点更新父节点(此处是区间最大值) 15 } 16 17 { //在main函数中的语句 18 update(1,1,n,ind,ans); 19 }
1 //单点修改的区间查询 2 int query(int o,int l,int r,int ql,int qr){ //ql、qr为需要查询的区间左右端点 3 if(ql>r||qr<l) return -1; //若当前结点和需要查找的区间不相交,则返回一个对于区间查询无关的值(如求和时返回0,求最大值时返回-1等) 4 if(ql<=l&&qr>=r) return st[o]; //若当前结点的区间被需要查询的区间覆盖,则返回当前结点的信息 5 int m=l+((r-l)>>1); 6 int p1=query(o<<1,l,m,ql,qr),p2=query((o<<1)|1,m+1,r,ql,qr); //p1为查询左儿子结点得到的信息,p2为查询右儿子结点得到的信息 7 return max(p1,p2); //综合两个儿子结点的信息并返回 8 } 9 10 { //main函数中的语句 11 printf("%dn",query(1,1,n,a,b)); 12 }
然后是线段数的区间修改以及相应的查询:
区间修改用到了lazy的思想,即当一个区间需要更新时,只递归更新到那一层结点,并将其下层结点所需要更新的信息保存在数组中,然后返回,只有当下次遍历到那个结点(更新过程中或查询过程中),才将那个结点的修改信息传递下去,这样就避免了区间修改的每个值的修改
区间修改(包括区间加值和区间赋值)及相应查询:
1 //区间加值 2 void pushup(int o){ //pushup函数,该函数本身是将当前结点用左右子节点的信息更新,此处求区间和,用于update中将结点信息传递完返回后更新父节点 3 st[o]=st[o<<1]+st[o<<1|1]; 4 } 5 6 void pushdown(int o,int l,int r){ //pushdown函数,将o结点的信息传递到左右子节点上 7 if(add[o]){ //当父节点有更新信息时才向下传递信息 8 add[o<<1]+=add[o]; //左右儿子结点均加上父节点的更新值 9 add[o<<1|1]+=add[o]; 10 int m=l+((r-l)>>1); 11 st[o<<1]+=add[o]*(m-l+1); //左右儿子结点均按照需要加的值总和更新结点信息 12 st[o<<1|1]+=add[o]*(r-m); 13 add[o]=0; //信息传递完之后就可以将父节点的更新信息删除 14 } 15 } 16 17 void update(int o,int l,int r,int ql,int qr,int addv){ //ql、qr为需要更新的区间左右端点,addv为需要增加的值 18 if(ql<=l&&qr>=r){ //与单点更新一样,当当前结点被需要更新的区间覆盖时 19 add[o]+=addv; //更新该结点的所需更新信息 20 st[o]+=addv*(r-l+1); //更新该结点信息 21 return; //根据lazy思想,由于不需要遍历到下层结点,因此不需要继续向下更新,直接返回 22 } 23 24 pushdown(o,l,r); //将当前结点的所需更新信息传递到下一层(其左右儿子结点) 25 int m=l+((r-l)>>1); 26 if(ql<=m)update(o<<1,l,m,ql,qr,addv); //当需更新区间在当前结点的左儿子结点内,则更新左儿子结点 27 if(qr>=m+1)update(o<<1|1,m+1,r,ql,qr,addv); //当需更新区间在当前结点的右儿子结点内,则更新右儿子结点 28 pushup(o); //递归回上层时一步一步更新回父节点 29 } 30 31 ll query(int o,int l,int r,int ql,int qr){ //ql、qr为需要查询的区间 32 if(ql<=l&&qr>=r) return st[o]; //若当前结点覆盖区间即为需要查询的区间,则直接返回当前结点的信息 33 pushdown(o,l,r); //将当前结点的更新信息传递给其左右子节点 34 int m=l+((r-l)>>1); 35 ll ans=0; //所需查询的结果 36 if(ql<=m)ans+=query(o<<1,l,m,ql,qr); //若所需查询的区间与当前结点的左子节点有交集,则结果加上查询其左子节点的结果 37 if(qr>=m+1)ans+=query(o<<1|1,m+1,r,ql,qr); //若所需查询的区间与当前结点的右子节点有交集,则结果加上查询其右子节点的结果 38 return ans; 39 }
1 //区间改值(其实只有pushdow函数和update中修改部分与区间加值不同) 2 void pushup(int o){ 3 st[o]=st[o<<1]+st[o<<1|1]; 4 } 5 6 void pushdown(int o,int l,int r){ //pushdown和区间加值不同,改值时修改结点信息只需要对修改后的信息求和即可,不用加上原信息 7 if(change[o]){ 8 int c=change[o]; 9 change[o<<1]=c; 10 change[o<<1|1]=c; 11 int m=l+((r-l)>>1); 12 st[o<<1]=(m-l+1)*c; 13 st[o<<1|1]=(r-m)*c; 14 change[o]=0; 15 } 16 } 17 18 void update(int o,int l,int r,int ql,int qr,int c){ 19 if(ql<=l&&qr>=r){ //同样更新结点信息和区间加值不同 20 change[o]=c; 21 st[o]=(r-l+1)*c; 22 return; 23 } 24 25 pushdown(o,l,r); 26 int m=l+((r-l)>>1); 27 if(ql<=m)update(o<<1,l,m,ql,qr,c); 28 if(qr>=m+1)update(o<<1|1,m+1,r,ql,qr,c); 29 pushup(o); 30 } 31 32 int query(int o,int l,int r,int ql,int qr){ 33 if(ql<=l&&qr>=r) return st[o]; 34 pushdown(o,l,r); 35 int m=l+((r-l)>>1); 36 int ans=0; 37 if(ql<=m)ans+=query(o<<1,l,m,ql,qr); 38 if(qr>=m+1)ans+=query(o<<1|1,m+1,r,ql,qr); 39 return ans; 40 }
看到好的链接:https://blog.csdn.net/zxzxzx0119/article/details/79838261
0 条评论