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;
}
posted @ 2023-02-26 14:39  小又又yyyy  阅读(19)  评论(0编辑  收藏  举报