忘记时候看一看
数据结构
Trie
int n,m;
int trie[maxn][30],tot=1;
int en[maxn];
string sn;
void inser(string s){//trie插入
int ch,len=s.length(),p=1;
for(int i=0;i<len;i++){
ch=s[i]-'a';
if(trie[p][ch]==0)trie[p][ch]=++tot;
p=trie[p][ch];
}
en[p]=true;
}
int sear(string s){//检索字符串是否存在
int len=s.length(),p=1,ch,sum=0;
for(int i=0;i<len;i++){
ch=s[i]-'a';
if(trie[p][ch]==0)return false;
}
return en[p];
}
Manacher
D2 Prefix-Suffix Palindrome(HARD) 题解
马拉车:求最大回文串
/*
String:加'#'处理后的回文串
MaxR:最长回文半径
flag:最长回文半径对应的中心点下标
cnt[i]:以i为中心对应的回文半径
length:String长度
*/
int cnt[maxn*2];
char ts[maxn*2];
void manacher(string s,int len){
int l=0;
ts[l++]='$';
ts[l++]='#';
for(int i=0;i<len;i++){
ts[l++]=s[i];
ts[l++]='#';
}
ts[l]=0;
int maxr=0,flag=0;
for(int i=0;i<l;i++){
cnt[i]=maxr>i?min(cnt[2*flag-i],maxr-i):1;
while(ts[i+cnt[i]]==ts[i-cnt[i]])
cnt[i]++;
if(i+cnt[i]>maxr){
maxr=i+cnt[i];
flag=i;
}
}
}
并查集
D. Recommendations(贪心、并查集)
D. Secret Passwords(并查集)
LL fin(LL x){
if(f[x]==0)
return x;
return f[x]=fin(f[x]);
}
void mix(LL fa,LL son){
LL x=fin(fa),y=fin(son);
if(x!=y)
f[y]=x;
}
dfs遍历树
C. Linova and Kingdom(Codeforces Round #635 (Div. 2))(贪心、dfs)
vector<int> G[maxn];
LL ans[maxn],del[maxn];//ans是路径长度,del是后继节点个数
int co=0,tt;
bool cmp(LL a,LL b){return a>b;}
LL dfs(int nw,int fa,int len){
ans[nw]+=1ll*len;
int sum=0;
for(int i=0;i<G[nw].size();i++){
if(G[nw][i]==fa)continue;
sum+=dfs(G[nw][i],nw,len+1);
}
del[nw]=sum+G[nw].size()-1;
return del[nw];//返回当前点nw的后继节点个数(路径长度这么求大憨憨球球长点🧠?
}
数论
素数筛
POJ2689 Prime Distance(素数、线性筛、试除法)
LL v[maxn],prime[maxn];//v存质数,vis判断是不是质数
bool mp[maxn];
int primes(LL n){
int m=0;
for(LL i=2;i<=n;i++){
if(v[i]==0){//i是质数
v[i]=i;prime[++m]=i;
}
for(int j=1;j<=m;j++){
if(prime[j]>v[i]||prime[j]>n/i)break;
v[i*prime[j]]=prime[j];
}
}
return m;
}
整除分块
cin>>n;
int ans=0;
a[ans]=0;
for(int l=1,r;l<=n;l=r+1){
r=n/(n/l);
ans++;
//cout<<ans<<" "<<l<<" "<<r<<endl;
a[ans]=n/r;
}
cout<<ans+1<<endl;
sort(a,a+ans+1);
for(int i=0;i<=ans;i++){
cout<<a[i]<<" ";
}
cout<<endl;
二次剩余
template<typename T>
inline int pow(int x, T y)
{
int res = 1; x %= MOD;
for (; y; y >>= 1, x = (LL)x*x%MOD) if (y & 1) res = (LL)res*x%MOD;
return res;
}
inline int Quadratic_residue(const int a)
{
if (a == 0)return 0;
int b = (rand() << 14 ^ rand()) % MOD;
while (pow(b, (MOD - 1) >> 1) != MOD - 1)b = (rand() << 14 ^ rand()) % MOD;
int s = MOD - 1, t = 0, x, inv = pow(a, MOD - 2), f = 1;
while (!(s & 1))s >>= 1, t++, f <<= 1;
t--, x = pow(a, (s + 1) >> 1), f >>= 1;
while (t)
{
f >>= 1;
if (pow((int)((LL)inv*x%MOD*x%MOD), f) != 1) x = (LL)x*pow(b, s) % MOD;
t--, s <<= 1;
}
return min(x, MOD - x);
}
int main() {
int n;
scanf("%d", &n);
printf("%d\n", Quadratic_residue(n));
return 0;
}
欧拉降幂公式
LL euler_phi(LL n) {//求解欧拉函数
LL k = (LL)sqrt(n + 0.5);
LL ans = n;
for (int i = 2; i <= k; i++) {
if (n % i == 0) {
ans = ans / i * (i - 1);
while (n % i == 0) n /= i;
}
}
if (n > 1) ans = ans / n * (n - 1);
return ans;
}
数组
upper_bound()&&lower_bound()
upper:从小到大排序的数组里第一个大于的元素//从大到小第一个小于的元素
lower:从小到大排序数组里第一个大于等于的元素//从大到小第一个小于等于的元素
对递增数组里小于a[i]的数字计数:cf 1324D. Pair of Topics
for(int i=1;i<=n;i++){
int tt=min(n,lower_bound(c+1,c+1+n,a[i])-c);
if(c[tt]>=a[i])
tt--;
//cout<<tt<<endl;
ans+=(1ll*tt);
}
字符串操作
删除下标为x的字符
if(i-1>0&&s[i-1]==s[i]-1){
string::iterator it=s.begin()+i;
while(i+1<s.length()&&s[i]==s[i+1]){
s.erase(it);
t++;
}
}
字符串反转
tt就是s[i]反转后的
string tt="";
tt+=s[i];
reverse(tt.begin(),tt.end());
string nw中的下标为nww,i的反转
reverse(nw.begin()+nww,nw.begin()+i+1);
字符串插入
头插
ans.insert(0,tt);
尾插
ans+=tt;
长度
ans的字符个数 注意下标从0开始
ans.length();
截取
从start_point(下标)开始的长length的子串
s+=ans.substr(start_point,length);
比较
直接运算符
字典序排序
sort(tt.begin(),tt.end());
map操作
二维
C. Yet Another Walking Robot:题面
题解
map< int,map<int,int> > m;
m[x][y]=1;
下标是string
map<string,int> mp;
find(x)
找到第一个下标为x(内容)的位置,返回指针
Berry Jam
for(int i=n;i<=n*2;i++){
map<int,int>::iterator it=pre.find(sum[i]-sum[2*n]);
if(it!=pre.end())
ans=min(ans,i-it->second);
}
图
链式前向星
存图与加边
POJ 3764 The xor-longest Path
int Head[N], Edge[N*2], Leng[N*2], Next[N*2], num;
void add(int x, int y, int z) {
Edge[++tot] = y;
Leng[tot] = z;
Next[tot] = Head[x];
Head[x] = tot;
}
int main(){
for (int i = 1; i < n; i++) {
int u, v, w;
scanf("%d %d %d", &u, &v, &w);
add(u, v, w);
add(v, u, w);
}
}
dfs遍历
bool v[N];
void dfs(int x) {
for (int i = Head[x]; i; i = Next[i]) {
int y = Edge[i], z = Leng[i];
if (v[y]) continue;
v[y] = 1;
d[y] = d[x] ^ z;//修改dfs操作
dfs(y);
}
}