CCF-CSP准备
dfs序
void dfs(int x,int fa){
in[x] = ++cnt;
for (int i = head[x];i;i = ed[i].nxt){
int to = ed[i].to;
if (to == fa) continue;
dfs(to,x);
}
out[x] = cnt;
}
离散化
sort(que+1,que+1+cnt);
len = unique(que+1,que+cnt+1)-que-1;
for(int i = 1;i <= n;i ++){
s[i] = lower_bound(que + 1, que + len + 1, k[i]) - que;
}
快速幂
int qpow(int x,int k){
int res = 1;
while (k){
if (k&1) (res *= x) %= mod;
(x *= x) %= mod;
k >>= 1;
}
return res % mod;
}
map的应用
struct node{
int x = 0,y = 0;
bool operator < (const node &a)const{
if (x != a.x) return x < a.x;
return y < a.y;
}
}fig[maxn];
map<node,int> g;
kmp
int main(){
scanf ("%s",s+1);scanf ("%s",t+1);
int j = 0;
int lent = strlen(t+1),lens = strlen(s+1);
for (int i = 2;i <= lent;i++){
while (j&&t[i] != t[j+1]) j = fail[j];
if (t[i] == t[j+1]) j++;
fail[i] = j;
}
j = 0;
for (int i = 1;i <= lens;i++){
while (j&&s[i] != t[j+1]) j = fail[j];
if (s[i] == t[j+1]) j++;
if (j == lent){
cout<<i-lent+1<<endl;
j = fail[j];
}
}
for (int i = 1;i <= lent;i++) cout<<fail[i]<<" ";
cout<<endl;
return 0;
}
拓扑
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <cstring>
#define O(x) cout<<#x<<" "<<x<<endl;
#define B cout<<"Breakpoint"<<endl;
using namespace std;
int read(){
int x = 1,a = 0;char ch = getchar();
while (ch < '0'||ch > '9'){if (ch == '-') x = -1;ch = getchar();}
while (ch >= '0'&&ch <= '9'){a = a*10+ch-'0';ch = getchar();}
return x*a;
}
const int maxn = 1e6+10;
struct node{
int tot = 0;
int head[maxn],to[maxn],nxt[maxn],w[maxn];
void add(int u,int v,int val){
to[++tot] = v,nxt[tot] = head[u],w[tot] = val,head[u] = tot;
}
}ed;
int n,m,cnt;
queue<int> q;
int num,du[maxn],c[maxn],dis[maxn];
void topsort(){
for (int i = 1;i <= n+m;i++) if (!du[i]) q.push(i);
while (!q.empty()){
int x = q.front();
c[++num] = x;q.pop();
for (int i = ed.head[x];i;i = ed.nxt[i]){
int to = ed.to[i];
du[to]--;
if (!du[to]) q.push(to);
}
}
}
int st[maxn],vis[maxn];
int main(){
n = read(),m = read();
cnt = n;
for (int i = 1;i <= n;i++) dis[i] = 1;
for (int i = 1;i <= m;i++){
int s = read();
++cnt;
for (int j = 1;j <= s;j++) st[j] = read(),vis[st[j]] = 1;
for (int j = st[1];j <= st[s];j++){
if (vis[j]) ed.add(cnt,j,1),du[j]++;
else ed.add(j,cnt,0),du[cnt]++;
}
for (int j = 1;j <= s;j++) vis[st[j]] = 0;
}
topsort();
for (int i = 1;i <= num;i++){
int x = c[i];
// cout<<x<<endl;
for (int j = ed.head[x];j;j = ed.nxt[j]){
int to = ed.to[j],w = ed.w[j];
dis[to] = max(dis[to],dis[x]+w);
}
}
int ans = 0;
for (int i = 1;i <= num;i++) ans = max(ans,dis[i]);
cout<<ans<<endl;
return 0;
}
筛法
int prime[maxn];
int visit[maxn];
void Prime(){
mem(visit,0);
mem(prime, 0);
for (int i = 2;i <= maxn; i++) {
cout<<" i = "<<i<<endl;
if (!visit[i]) {
prime[++prime[0]] = i; //纪录素数, 这个prime[0] 相当于 cnt,用来计数
}
for (int j = 1; j <=prime[0] && i*prime[j] <= maxn; j++) {
// cout<<" j = "<<j<<" prime["<<j<<"]"<<" = "<<prime[j]<<" i*prime[j] = "<<i*prime[j]<<endl;
visit[i*prime[j]] = 1;
if (i % prime[j] == 0) {
break;
}
}
}
}
LCS
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int n,num;
int s1[1000005],s2[100005],c[100005];
struct node{
int x,y;
};
node a[1000005];
inline int read(){
int x = 1,a = 0;char ch = getchar();
while (ch < '0' || ch > '9'){if (ch == '-')x = -1;ch = getchar();}
while(ch <= '9'&&ch >= '0'){a = a * 10 + ch - '0';ch = getchar();}
return x*a;
}
bool cmp(node x,node y){
return x.x<y.x;
}
int main()
{
// freopen("1.in","r",stdin);
// freopen("1.out","w",stdout);
n = read();
for (int i = 1;i <= n ;i++){
s1[i] = read();
a[s1[i]].x=i;
}
for (int i = 1;i <= n;i++){
s2[i] = read();
a[s2[i]].y=i;
}
sort(a+1,a+n+1,cmp);
for (int i = 1;i <= n;i++){
if (c[num] < a[i].y) c[++num] = a[i].y;
else{
int pos = lower_bound(c+1,c+num+1,a[i].y)-c;
c[pos] = a[i].y;
}
}
printf ("%d",num);
return 0;
}
单调队列优化dp
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
int q1[1000005],q2[1000005];
int n,k,a[1000005];
void maxx(){
int head=1,t=0;
for (int i = 1;i <= n;i++){
while(head<=t&&q1[head]+k<=i) head++;//查看队首是否超过限定长度,超过就弹出
while(head<=t&&a[i]>a[q1[t]]) t--;//维护单调性
q1[++t]=i;
if (i>=k) cout<<a[q1[head]]<<" ";
}
}
void minn(){
int head=1,t=0;
for (int i = 1;i <= n;i++){
while(head<=t&&q2[head]+k<=i) head++;//查看队首是否超过限定长度,超过就弹出
while(head<=t&&a[i]<a[q2[t]]) t--;//维护单调性
q2[++t]=i;
if (i>=k) cout<<a[q2[head]]<<" ";
}
}
int main(){
scanf ("%d%d",&n,&k);
for (int i = 1;i <= n;i++) scanf ("%d",&a[i]);
minn();
cout<<endl;
maxx();
return 0;
}