zoukankan      html  css  js  c++  java
  • NOIP知识点&&模板整理【更新中】

    NOIP知识点&&模板整理

    数据结构


    线段树1

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 100005;
    typedef long long ll;
    ll read()
    {
    	char c = getchar(), last = ' ';
    	ll ans = 0;
    	while(c < '0' || c > '9') last = c, c = getchar();
    	while(c >= '0' && c <= '9') ans = ans * 10 + c - '0', c = getchar();
    	if(last == '-') ans = -ans;
    	return ans;
    }
    ll a[N];
    namespace seg
    {
    	ll sum[N << 2], lazy[N << 2];
    	void pushup(int cnt)
    	{
    		sum[cnt] = sum[cnt << 1] + sum[cnt << 1 | 1];
    	}
    	void pushdown(int cnt, int l, int r)
    	{
    		int mid = l + r >> 1;
    		//sum[cnt] += lazy[cnt] * (r - l + 1);
    		sum[cnt << 1] += lazy[cnt] * (mid - l + 1);
    		sum[cnt << 1 | 1] += lazy[cnt] * (r - mid);
    		lazy[cnt << 1] += lazy[cnt];
    		lazy[cnt << 1 | 1] += lazy[cnt];
    		lazy[cnt] = 0;
     	}
     	void build(int cnt, int l, int r)
     	{
     		if(l == r) 
    		{
    		 	sum[cnt] = a[l];
    		 	return;
    		}
     		int mid = l + r >> 1;
     		build(cnt << 1, l, mid);
     		build(cnt << 1 | 1, mid + 1, r);
     		pushup(cnt);
    	 }
     	void add(int cnt, int l, int r, int nl, int nr, ll k)
     	{
     		if(l >= nl && r <= nr) 
     		{
     			sum[cnt] += (r - l + 1) * k;
     			lazy[cnt] += k;
     			return;
    		}
    		int mid = l + r >> 1;
    		pushdown(cnt, l, r);
    		if(nl <= mid) add(cnt << 1, l, mid, nl, nr, k);
    		if(nr > mid) add(cnt << 1 | 1, mid + 1, r, nl, nr, k);
    		pushup(cnt);
    	}
    	ll query(int cnt, int l, int r, int nl, int nr)
    	{
    		if(l >= nl && r <= nr) return sum[cnt];
    		int mid = l + r >> 1;
    		ll ans = 0;
    		pushdown(cnt, l, r);
    		if(nl <= mid) ans += query(cnt << 1, l, mid, nl, nr);
    		if(nr > mid) ans += query(cnt << 1 | 1, mid + 1, r, nl, nr);
    		return ans;
    	}
    }
    int n, m;
    int main()
    {
    	scanf("%d%d", &n, &m);
    	for(int i = 1; i <= n; i ++) a[i] = read();
    	seg::build(1, 1, n);
    	int opt, x, y;
    	ll k, ans = 0;
    	for(int i = 1; i <= m; i ++)
    	{
    		opt = read(), x = read(), y = read();
    		if(opt == 1)
    		{
    			k = read();
    			seg::add(1, 1, n, x, y, k);
    		}
    		else if(opt == 2)
    		{
    			ans = seg::query(1, 1, n, x, y);
    			printf("%lld
    ", ans);
    		}
    	}
    }
    

    线段树2

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 100005;
    typedef long long ll;
    ll read()
    {
    	char c = getchar(), last = ' ';
    	ll ans = 0;
    	while(c < '0' || c > '9') last = c, c = getchar();
    	while(c >= '0' && c <= '9') ans = ans * 10 + c - '0', c = getchar();
    	if(last == '-') ans = -ans;
    	return ans;
    }
    int n, m, p;
    ll a[N];
    namespace seg
    {
    	ll sum[N << 2], lazy1[N << 2], lazy2[N << 2];
    	void pushup(int cnt)
    	{
    		sum[cnt] = (sum[cnt << 1] + sum[cnt << 1 | 1]) % p;
    	}
    	void pushdown(int cnt, int l, int r)
    	{
    		int mid = l + r >> 1;
    		lazy1[cnt << 1] = ((lazy1[cnt << 1] * lazy2[cnt] % p) + lazy1[cnt] % p) % p;
    		lazy1[cnt << 1 | 1] = ((lazy1[cnt << 1 | 1] * lazy2[cnt] % p) + lazy1[cnt]) % p;
    		lazy2[cnt << 1] = lazy2[cnt << 1] * lazy2[cnt] % p;
    		lazy2[cnt << 1 | 1] = lazy2[cnt << 1 | 1] * lazy2[cnt] % p;
    		sum[cnt << 1] = ((lazy1[cnt] * (mid - l + 1) % p) + lazy2[cnt] * sum[cnt << 1] % p) % p;
    		sum[cnt << 1 | 1] = ((lazy1[cnt] * (r - mid) % p) + lazy2[cnt] * sum[cnt << 1 | 1] % p) % p;
    		lazy1[cnt] = 0; 
    		lazy2[cnt] = 1;
     	}
     	void build(int cnt, int l, int r)
     	{
     		lazy2[cnt] = 1;
     		if(l == r) 
    		{
    		 	sum[cnt] = a[l] % p;
    		 	return;
    		}
     		int mid = l + r >> 1;
     		build(cnt << 1, l, mid);
     		build(cnt << 1 | 1, mid + 1, r);
     		pushup(cnt);
    	 }
     	void add1(int cnt, int l, int r, int nl, int nr, ll k)
     	{
     		if(l >= nl && r <= nr) 
     		{
     			sum[cnt] = (sum[cnt] + (r - l + 1) * k % p) % p;
     			lazy1[cnt] = (lazy1[cnt] + k % p) % p;
     			return;
    		}
    		int mid = l + r >> 1;
    		pushdown(cnt, l, r);
    		if(nl <= mid) add1(cnt << 1, l, mid, nl, nr, k);
    		if(nr > mid) add1(cnt << 1 | 1, mid + 1, r, nl, nr, k);
    		pushup(cnt);
    	}
    	void add2(int cnt, int l, int r, int nl, int nr, ll k)
     	{
     		if(l >= nl && r <= nr) 
     		{
     			sum[cnt] = sum[cnt] * k % p;
     			lazy1[cnt] = lazy1[cnt] * k % p;
     			lazy2[cnt] = lazy2[cnt] * k % p;
     			return;
    		}
    		int mid = l + r >> 1;
    		pushdown(cnt, l, r);
    		if(nl <= mid) add2(cnt << 1, l, mid, nl, nr, k);
    		if(nr > mid) add2(cnt << 1 | 1, mid + 1, r, nl, nr, k);
    		pushup(cnt);
    	}
    	ll query(int cnt, int l, int r, int nl, int nr)
    	{
    		if(l >= nl && r <= nr) return sum[cnt] % p;
    		int mid = l + r >> 1;
    		ll ans = 0;
    		pushdown(cnt, l, r);
    		if(nl <= mid) ans += query(cnt << 1, l, mid, nl, nr);
    		if(nr > mid) ans += query(cnt << 1 | 1, mid + 1, r, nl, nr);
    		return ans;
    	}
    }
    
    int main()
    {
    	scanf("%d%d%d", &n, &m, &p);
    	for(int i = 1; i <= n; i ++) a[i] = read();
    	seg::build(1, 1, n);
    	int opt, x, y;
    	ll k, ans = 0;
    	for(int i = 1; i <= m; i ++)
    	{
    		
    		opt = read(), x = read(), y = read();
    		if(opt == 1)
    		{
    			k = read();
    			seg::add2(1, 1, n, x, y, k);
    		}
    		else if(opt == 2)
    		{
    			k = read();
    			seg::add1(1, 1, n, x, y, k);
    		}
    		else if(opt == 3)
    		{
    			ans = seg::query(1, 1, n, x, y);
    			printf("%lld
    ", ans % p);
    		}
    	}
    }
    

    树状数组1

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 500005;
    typedef long long ll;
    ll read()
    {
    	char c = getchar(), last = ' ';
    	ll ans = 0;
    	while(c < '0' || c > '9') last = c, c = getchar();
    	while(c >= '0' && c <= '9') ans = ans * 10 + c - '0', c = getchar();
    	if(last == '-') ans = -ans;
    	return ans;
    }
    int n, m;
    ll a[N];
    namespace bit
    {
    	ll s[N];
    	int low(int x){return x & -x;}
    	void add(int x, ll k){for(; x <= n; x += low(x)) s[x] += k;}
    	ll query(int x){ll ans = 0; for(; x; x -= low(x)) ans += s[x]; return ans;}
    }
    int main()
    {
    	scanf("%d%d", &n, &m);
    	for(int i = 1; i <= n; i ++) bit::add(i, read());
    	ll opt, x, y;
    	for(int i = 1; i <= m; i ++)
    	{
    		opt = read(), x = read(), y = read();
    		if(opt == 1) bit::add(x, y);
    		else if(opt == 2) printf("%lld
    ", bit::query(y) - bit::query(x - 1));
    	}
    }
    

    树状数组2

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 500005;
    typedef long long ll;
    ll read()
    {
    	char c = getchar(), last = ' ';
    	ll ans = 0;
    	while(c < '0' || c > '9') last = c, c = getchar();
    	while(c >= '0' && c <= '9') ans = ans * 10 + c - '0', c = getchar();
    	if(last == '-') ans = -ans;
    	return ans;
    }
    int n, m;
    ll a[N];
    namespace bit
    {
    	ll s[N];
    	int low(int x){return x & -x;}
    	void add(int x, ll k){for(; x <= n; x += low(x)) s[x] += k;}
    	ll query(int x){ll ans = 0; for(; x; x -= low(x)) ans += s[x]; return ans;}
    }
    int main()
    {
    	scanf("%d%d", &n, &m);
    	for(int i = 1; i <= n; i ++) a[i] = read();
    	ll opt, x, y, k;
    	for(int i = 1; i <= m; i ++)
    	{
    		opt = read(), x = read();
    		if(opt == 1)
    		{
    			y = read(), k = read();
    			bit::add(x, k);
    			bit::add(y + 1, -k);
    		} 
    		else if(opt == 2) printf("%lld
    ", bit::query(x) + a[x]);
    	}
    }
    

    st表

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int read()
    {
    	char c = getchar(), last = ' ';
    	int ans = 0;
    	while(c < '0' || c > '9') last = c, c = getchar();
    	while(c >= '0' && c <= '9') ans = ans * 10 + c - '0', c = getchar();
    	if(last == '-') ans = -ans;
    	return ans;
    }
    const int N = 100005;
    int n, m;
    int st[N][21], Log[N];
    int find(int x, int y)
    {
    	int t = y - x + 1;
    	return max(st[x][Log[t]], st[y - (1 << Log[t]) + 1][Log[t]]);
    }
    int main()
    {
    	scanf("%d%d", &n, &m);
    	for(int i = 1; (1 << i) < N; i ++) Log[1 << i] = i;
    	for(int i = 1; i <= n; i ++) if(Log[i] == 0) Log[i] = Log[i - 1]; 
    	for(int i = 1; i <= n; i ++) st[i][0] = read();
    	for(int i = 1; (1 << i) <= N; i ++)
    		for(int j = 1; (j + (1 << i - 1)) <= n; j ++)
    			st[j][i] = max(st[j][i - 1], st[j + (1 << (i - 1))][i - 1]);
    	for(int i = 1, x, y; i <= m; i ++)
    	{
    		x = read(), y = read();
    		printf("%d
    ", find(x, y));
    	}
    	
    }
    

    单调队列(滑动窗口)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int read()
    {
    	char c = getchar(), last = ' ';
    	int ans = 0;
    	while(c < '0' || c > '9') last = c, c = getchar();
    	while(c >= '0' && c <= '9') ans = ans * 10 + c - '0', c = getchar();
    	if(last == '-') ans = -ans;
    	return ans;
    }
    const int N = 1000005;
    int n, k, a[N];
    int q[N], l, r;
    int main()
    {
    	n = read(), k =read();
    	for(int i = 1; i <= n; i ++) a[i] = read();
    	for(int i = 1; i <= n; i ++)
    	{
    		while(l <= r && i - q[l] + 1 > k) l ++;
    		while(l <= r && a[q[r]] >= a[i]) r --;
    		q[++r] = i;
    		if(i >= k)
    		printf("%d ", a[q[l]]);
    	}
    	printf("
    ");
    	l = 0, r = 0;
    	for(int i = 1; i <= n; i ++)
    	{
    		while(l <= r && i - q[l] + 1 > k) l ++;
    		while(l <= r && a[q[r]] <= a[i]) r --;
    		q[++r] = i;
    		if(i >= k)
    		printf("%d ", a[q[l]]);
    	}
    }
    

    平衡树(fhq treap)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 1100005;
    int read()
    {
    	int ans = 0;
    	char c = getchar(), last = ' ';
    	while(c < '0' || c > '9') last = c, c = getchar();
    	while(c >= '0' && c <= '9') ans = (ans << 1) + (ans << 3) + c - '0', c = getchar();
    	if(last == '-') ans = - ans;
    	return ans;
    }
    int ecnt;
    struct tree
    {
    	int l, r, siz, rad, val;
    }t[N<<2];
    unsigned long long seed = 1;
    int Rand()
    {
    	seed *= 260817;
    	return int(seed);
    }
    void update(int cnt)
    {
    	t[cnt].siz = t[t[cnt].l].siz + t[t[cnt].r].siz + 1;
    }
    
    int New(int x)
    {
    	t[++ecnt].val = x;
    	t[ecnt].rad = Rand();
    	t[ecnt].siz = 1;
    	return ecnt;
    }
    
    void split(int cnt, int k, int &x, int &y)
    {
    	if(!cnt)
    	{
    		x = y = 0;
    		return;
    	}
    	if(t[cnt].val <= k)
    	{
    		x = cnt;
    		split(t[cnt].r, k, t[cnt].r, y);
    	}
    	if(t[cnt].val > k)
    	{
    		y = cnt;
    		split(t[cnt].l, k, x, t[cnt].l);
    	}
    	update(cnt);
    }
    
    int merge(int x, int y)
    {
    	if(x == 0) return y;
    	if(y == 0) return x;
    	if(t[x].rad <= t[y].rad)
    	{
    		t[x].r = merge(t[x].r, y);
    		update(x);
    		return x;
    	}
    	else if(t[x].rad > t[y].rad)
    	{
    		t[y].l = merge(x, t[y].l);
    		update(y);
    		return y;
    	}
    }
    
    int kth(int cnt, int k)
    {
    	if(t[t[cnt].l].siz + 1 == k) return t[cnt].val;
    	if(t[t[cnt].l].siz >= k) return kth(t[cnt].l, k);
    	else return kth(t[cnt].r, k - t[t[cnt].l].siz - 1);
    }
    
    int n, m, rt;
    int last = 0, ans = 0;
    
    int main()
    {
    	//freopen("1.in", "r", stdin);
    	//freopen("1.out", "w", stdout); 
    	//srand(time(0));
    	scanf("%d%d", &n, &m);
    	int x, y, z, k, opt;
    	for(int i = 1; i <= n; i ++)
    	{
    		k = read();
    		split(rt, k, x, y);
    		rt = merge(merge(x, New(k)), y);
    	}
    	for(int i = 1; i <= m; i ++)
    	{
    		opt = read(), k = read();
    		k ^= last;
    		if(opt == 1) 
    		{
    			split(rt, k, x, y);
    			rt = merge(merge(x, New(k)), y);
    		}
    		if(opt == 2)
    		{
    			split(rt, k, x, y);
    			split(x, k - 1, x, z);
    			z = merge(t[z].l, t[z].r);
    			rt = merge(merge(x, z), y); 
    		}
    		if(opt == 3)
    		{
    			split(rt, k - 1, x, y);
    			last = t[x].siz + 1;
    			ans ^= last;
    			//printf("%lld
    ", last);
    			rt = merge(x, y);
    		}
    		if(opt == 4)
    		{
    			last = kth(rt, k);
    			ans ^= last;
    			//printf("%lld
    ", last);
    		}
    		if(opt == 5)
    		{
    			split(rt, k - 1, x, y);
    			last = kth(x, t[x].siz);
    			ans ^= last;
    			//printf("%lld
    ", last);
    			rt = merge(x, y);
    		}
    		if(opt == 6)
    		{
    			split(rt, k, x, y);
    			last = kth(y, 1);
    			ans ^= last;
    			//printf("%lld
    ", last);
    			rt = merge(x, y);
    		}
    	}
    	printf("%d", ans);
    }
    

    图论

    最小生成树

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int read()
    {
    	char c = getchar(), last = ' ';
    	int ans = 0;
    	while(c < '0' || c > '9') last = c, c = getchar();
    	while(c >= '0' && c <= '9') ans = ans * 10 + c - '0', c = getchar();
    	if(last == '-') ans = -ans;
    	return ans;
    }
    const int N = 5005, M = 200005;
    int n, m, fa[N], ans;
    int ecnt;
    struct edge
    {
    	int to, dis, from;
    }edg[M << 1];
    int find(int x)
    {
    	while(x != fa[x]) x = fa[x] = fa[fa[x]];
    	return x;
    }
    bool cmp(edge x, edge y)
    {
    	return x.dis < y.dis;
    }
    void kruscal()
    {
    	sort(edg + 1, edg + 1 + m, cmp);
    	int cnt = 0;
    	for(int i = 1; i <= m; i ++)
    	{
    		int u = edg[i].from, v = edg[i].to;
    		if(find(u) == find(v)) continue;
    		cnt ++;
    		ans += edg[i].dis;
    		fa[find(v)] = find(u);
    		if(cnt == n - 1) break;
    	}
    }
    int main()
    {
    	n = read(), m = read();
    	for(int i = 1; i <= n; i ++) fa[i] = i;
    	for(int i = 1; i <= m; i ++)
    	{
    		edg[++ecnt].from = read();
    		edg[ecnt].to = read();
    		edg[ecnt].dis = read();
    	}
    	kruscal();
    	printf("%d", ans);
    }
    

    单源最短路(dijkstra)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int read()
    {
    	char c = getchar(), last = ' ';
    	int ans = 0;
    	while(c < '0' || c > '9') last = c, c = getchar();
    	while(c >= '0' && c <= '9') ans = ans * 10 + c - '0', c = getchar();
    	if(last == '-') ans = -ans;
    	return ans;
    }
    const int N = 100005;
    int head[N], ecnt;
    struct edge
    {
    	int to, dis, nxt;
    }edg[N << 2];
    void add(int u, int v, int w)
    {
    	edg[++ecnt].to = v;
    	edg[ecnt].dis = w;
    	edg[ecnt].nxt = head[u];
    	head[u] = ecnt;
    }
    int n, m, s;
    int dis[N], vis[N];
    priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > q;
    void dij()
    {
    	memset(dis, 0x3f, sizeof(dis));
    	memset(vis, 0, sizeof(vis));
    	dis[s] = 0;
    	q.push(make_pair(0, s));
    	while(!q.empty())
    	{
    		int u = q.top().second;
    		q.pop();
    		if(vis[u]) continue;
    		vis[u] = 1;
    		for(int i = head[u]; i; i = edg[i].nxt)
    		{
    			int v = edg[i].to;
    			if(dis[v] > dis[u] + edg[i].dis)
    			{
    				dis[v] = dis[u] + edg[i].dis;
    				q.push(make_pair(dis[v], v));
    			}
    		}
    	}
    }
    int main()
    {
    	n = read(), m = read(), s = read();
    	for(int i = 1, u, v, w; i <= m; i ++)
    	{
    		u = read(), v = read(), w = read();
    		add(u, v, w);
    	}
    	dij();
    	for(int i = 1; i <= n; i ++) printf("%d ", dis[i]);
    }
    

    单源最短路(SPFA)

    #include<bits/stdc++.h>
    using namespace std;
    inline int read()
    {
    	int ans=0;
    	char last=' ',ch=getchar();
    	while(ch<'0'||ch>'9') last=ch,ch=getchar();
    	while(ch>='0'&&ch<='9') ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
    	if(last=='-')ans=-ans;
    	return ans;
    }
    const int N = 10005, M = 500005;
    int head[N], ecnt;
    struct edge
    {
    	int to, dis, nxt;
    }edg[M];
    void add(int u, int v, int w)
    {
    	edg[++ecnt].to = v;
    	edg[ecnt].dis = w;
    	edg[ecnt].nxt = head[u];
    	head[u] = ecnt;
    }
    int n, m, s;
    queue<int> q;
    int dis[N], in[N];
    void spfa()
    {
    	memset(dis, 0x3f, sizeof(dis));
    	q.push(s);
    	dis[s] = 0;
    	in[s] = 1;
    	while(!q.empty())
    	{
    		int u = q.front();
    		q.pop();
    		in[u] = 0;
    		for(int i = head[u]; i; i = edg[i].nxt)
    		{
    			int v = edg[i].to;
    			if(dis[v] > dis[u] + edg[i].dis)
    			{
    				dis[v] = dis[u] + edg[i].dis;
    				if(!in[v]) q.push(v), in[v] = 1;
    			}
    		}
    	}
    }
    int main()
    {
    
    	n = read(), m = read(), s = read();
    	for(int i = 1, u, v, w; i <= m; i ++)
    	{
    		u = read(), v = read(), w = read();
    		add(u, v, w);
    	}
    	spfa();
    	for(int i = 1; i <= n; i ++) 
    	{
    		if(dis[i] == 0x3f3f3f3f) printf("%d ", (1 << 31) - 1);
    		else printf("%d ", dis[i]);
    	}
    }
    

    负环

    #include<bits/stdc++.h>
    using namespace std;
    inline int read()
    {
    	int ans=0;
    	char last=' ',ch=getchar();
    	while(ch<'0'||ch>'9') last=ch,ch=getchar();
    	while(ch>='0'&&ch<='9') ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
    	if(last=='-')ans=-ans;
    	return ans;
    }
    const int N = 2005;
    int head[N], ecnt;
    struct edge
    {
    	int to, dis, nxt;
    }edg[N << 2];
    void add(int u, int v, int w)
    {
    	edg[++ecnt].to = v;
    	edg[ecnt].dis = w;
    	edg[ecnt].nxt = head[u];
    	head[u] = ecnt;
    }
    int n, m;
    queue<int> q;
    int dis[N], vis[N], in[N];
    bool spfa()
    {
    	memset(dis, 0x3f, sizeof(dis));
    	memset(vis, 0, sizeof(vis));
    	memset(in, 0, sizeof(in));
    	q.push(1);
    	dis[1] = 0;
    	in[1] = 1;
    	while(!q.empty())
    	{
    		int u = q.front();
    		q.pop();
    		in[u] = 0;
    		if(vis[u] == n - 1) return 1;
    		vis[u] ++;
    		for(int i = head[u]; i; i = edg[i].nxt)
    		{
    			int v = edg[i].to;
    			if(dis[v] > dis[u] + edg[i].dis)
    			{
    				dis[v] = dis[u] + edg[i].dis;
    				if(!in[v]) q.push(v), in[v] = 1;
    			}
    		}
    	}
    	return 0;
    }
    int t;
    int main()
    {
    	t = read();
    	while(t --)
    	{
    		ecnt = 0;
    		memset(head, 0, sizeof(head));
    		n = read(), m = read();
    		for(int i = 1, u, v, w; i <= m; i ++)
    		{
    			u = read(), v = read(), w = read();
    			if(w >= 0) add(u, v, w), add(v, u, w);
    			else add(u, v, w);
    		}
    		if(spfa()) printf("YES
    ");
    		else printf("NO
    ");
    	}
    	
    }
    

    差分约束

    #include<bits/stdc++.h>
    using namespace std;
    inline int read()
    {
    	int ans=0;
    	char last=' ',ch=getchar();
    	while(ch<'0'||ch>'9') last=ch,ch=getchar();
    	while(ch>='0'&&ch<='9') ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
    	if(last=='-')ans=-ans;
    	return ans;
    }
    const int N = 100005;
    int head[N], ecnt;
    struct edge
    {
    	int to, dis, nxt;
    }edg[N << 2];
    void add(int u, int v, int w)
    {
    	edg[++ecnt].to = v;
    	edg[ecnt].dis = w;
    	edg[ecnt].nxt = head[u];
    	head[u] = ecnt;
    }
    int n, m;
    queue<int> q;
    int dis[N], vis[N], in[N];
    bool spfa()
    {
    	q.push(0);
    	in[0] = 1;
    	while(!q.empty())
    	{
    		int u = q.front();
    		q.pop();
    		in[u] = 0;
    		if(vis[u] == n - 1) return 1;
    		vis[u] ++;
    		for(int i = head[u]; i; i = edg[i].nxt)
    		{
    			int v = edg[i].to;
    			if(dis[v] < dis[u] + edg[i].dis)
    			{
    				dis[v] = dis[u] + edg[i].dis;
    				if(!in[v]) q.push(v), in[v] = 1;
    			}
    		}
    	}
    	return 0;
    }
    int main()
    {
    	n = read(), m = read();
    	for(int i = 1; i <= n; i ++) add(0, i, 1);
    	for(int i = 1, u, v, w; i <= m; i ++)
    	{
    		u = read(), v = read(), w = read();
    		add(u, v, -w);
    	}
    	if(spfa()) printf("NO");
    	else for(int i = 1; i <= n; i ++) printf("%d ", dis[i]);
    }
    

    LCA(最近公共祖先)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int read()
    {
    	char c = getchar(), last = ' ';
    	int ans = 0;
    	while(c < '0' || c > '9') last = c, c = getchar();
    	while(c >= '0' && c <= '9') ans = ans * 10 + c - '0', c = getchar();
    	if(last == '-') ans = -ans;
    	return ans;
    }
    const int N = 500005;
    int head[N], ecnt;
    struct edge
    {
    	int to, nxt;
    }edg[N << 2];
    void add(int u, int v)
    {
    	edg[++ecnt].to = v;
    	edg[ecnt].nxt = head[u];
    	head[u] = ecnt;
    }
    int n, m, s;
    int fa[N][24], dep[N], cnt;
    void dfs(int x, int f)
    {
    	for(int i = head[x]; i; i = edg[i].nxt)
    	{
    		int v = edg[i].to;
    		if(v == f) continue;
    		dep[v] = dep[x] + 1;
    		fa[v][0] = x;
    		dfs(v, x);
    	}
    }
    int find(int x, int y)
    {
    	if(dep[x] < dep[y]) swap(x, y);
    	int d = dep[x] - dep[y];
    	for(int i = 22; i >= 0; i --)
    	{
    		if(d & (1 << i)) x = fa[x][i];
    	}
    	if(x == y) return x;
    	for(int i = 22; i >= 0; i --)
    	{
    		if(fa[x][i] != fa[y][i]) 
    		{
    			x = fa[x][i]; 
    			y = fa[y][i];
    		}
    	}
    	return fa[x][0];
    }
    int main()
    {
    	n = read(), m = read(), s = read();
    	for(int i = 1, x, y; i < n; i ++) 
    	{
    		x = read(), y = read();
    		add(x, y);
    		add(y, x);
    	}
    	dep[s] = 1;
    	dfs(s, s);
    	for(int i = 1; i <= 23; i ++) 
    	{
    		for(int j = 1; j <= n; j ++)
    		{
    			fa[j][i] = fa[fa[j][i - 1]][i - 1];
    		}
    	}
    	for(int i = 1, x, y; i <= m; i ++)
    	{
    		x = read(), y = read();
    		printf("%d
    ", find(x, y));
    	}
    }
    

    树的直径(dfs)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int read()
    {
    	char c = getchar(), last = ' ';
    	int ans = 0;
    	while(c < '0' || c > '9') last = c, c = getchar();
    	while(c >= '0' && c <= '9') ans = ans * 10 + c - '0', c = getchar();
    	if(last == '-') ans = -ans;
    	return ans;
    }
    const int N = 100005;
    int head[N], ecnt;
    struct edge
    {
    	int to, nxt, dis;
    }edg[N << 2];
    void add(int u, int v, int w)
    {
    	edg[++ecnt].to = v;
    	edg[ecnt].dis = w;
    	edg[ecnt].nxt = head[u];
    	head[u] = ecnt;
    }
    int n, k, s, maxn;
    int dis[N];
    void dfs(int x, int fa)
    {
    	for(int i = head[x]; i; i = edg[i].nxt)
    	{
    		int v = edg[i].to;
    		if(v == fa) continue;
    		dis[v] = dis[x] + edg[i].dis;
    		if(dis[v] > maxn) maxn = dis[v], s = v;
    		dfs(v, x);
    	}
    }
    int main()
    {
    	n = read();
    	for(int i = 1, u, v, w; i < n; i ++)
    	{
    		u = read(), v = read(), w = read();
    		add(u, v, w);
    		add(v, u, w);
    	}
    	dis[1] = 0, maxn = 0;
    	dfs(1, 1);
    	dis[s] = 0, maxn = 0;
    	dfs(s, s);
    	printf("%d", maxn);
    }
    

    树的直径(dp)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int read()
    {
    	char c = getchar(), last = ' ';
    	int ans = 0;
    	while(c < '0' || c > '9') last = c, c = getchar();
    	while(c >= '0' && c <= '9') ans = ans * 10 + c - '0', c = getchar();
    	if(last == '-') ans = -ans;
    	return ans;
    }
    const int N = 100005;
    int head[N], ecnt;
    struct edge
    {
    	int to, nxt, dis;
    }edg[N << 2];
    void add(int u, int v, int w)
    {
    	edg[++ecnt].to = v;
    	edg[ecnt].dis = w;
    	edg[ecnt].nxt = head[u];
    	head[u] = ecnt;
    }
    int n, k, s, ans;
    int f[N];
    void dp(int x, int fa)
    {
    	for(int i = head[x]; i; i = edg[i].nxt)
    	{
    		int v = edg[i].to;
    		if(v == fa) continue;
    		dp(v, x);
    		ans = max(ans, f[x] + edg[i].dis + f[v]);
    		f[x] = max(f[x], f[v] + edg[i].dis);
    	}
    }
    int main()
    {
    	n = read();
    	for(int i = 1, u, v, w; i < n; i ++)
    	{
    		u = read(), v = read(), w = read();
    		add(u, v, w);
    		add(v, u, w);
    	}
    	dp(1, 0);
    	printf("%d", ans);
    }
    

    缩点(tarjan)

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 10005, M = 100005;
    int n, m;
    int a[N];
    int head[N], head1[N], ecnt, ecnt1;
    struct edge
    {
    	int to, nxt;
    }edg[M], edg1[M];
    void add(int u, int v)
    {
    	edg[++ecnt].to = v;
    	edg[ecnt].nxt = head[u];
    	head[u] = ecnt;
    }
    
    namespace tar
    {
    	int low[N], dep[N], s[N], in[N], scc[N], val[N], top, cnt, ct;
    	void tarjan(int x)
    	{
    		low[x] = dep[x] = ++cnt;
    		s[top++] = x;
    		in[x] = 1;
    		for(int i = head[x]; i; i = edg[i].nxt)
    		{
    			int v = edg[i].to;
    			if(!dep[v])
    			{
    				tarjan(v);
    				low[x] = min(low[x], low[v]);
    			}
    			else if(in[v])
    			{
    				low[x] = min(low[x], dep[v]);
    			}
    		}
    		if(low[x] == dep[x])
    		{
    			ct ++;
    			while(s[top] != x)
    			{
    				top --;
    				in[s[top]] = 0;
    				scc[s[top]] = ct;
    				val[ct] += a[s[top]];
    			}
    		}
    	}
    }
    
    namespace top
    {
    	void add1(int u, int v)
    	{
    		edg1[++ecnt1].to = v;
    		edg1[ecnt1].nxt = head1[u];
    		head1[u] = ecnt1;
    	}
    	int in[N], f[N];
    	void build()
    	{
    		for(int i = 1; i <= n; i ++)
    		{
    			for(int j = head[i]; j; j = edg[j].nxt)
    			{
    				int v = edg[j].to;
    				if(tar::scc[i] != tar::scc[v])
    				{
    					add1(tar::scc[i], tar::scc[v]);
    					in[tar::scc[v]] ++;
    				}
    			}
    		}
    	}
    	int topo()
    	{
    		queue<int> q;
    		for(int i = 1; i <= tar::ct; i ++) 
    			if(in[i] == 0) q.push(i), f[i] = tar::val[i];
    		while(!q.empty())
    		{
    			int u = q.front();
    			q.pop();
    			for(int i = head1[u]; i; i = edg1[i].nxt)
    			{
    				int v = edg1[i].to;
    				f[v] = max(f[v], f[u] + tar::val[v]);
    				in[v] --;
    				if(in[v] == 0) q.push(v);
    			}
    		}
    		int ans = 0;
    		for(int i = 1; i <= tar::ct; i ++) ans = max(ans, f[i]);
    		return ans;
    	}
    }
    
    int main()
    {
    	scanf("%d%d", &n, &m);
    	for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
    	for(int i = 1, u, v; i <= m; i ++)
    	{
    		scanf("%d%d", &u, &v);
    		add(u, v);
    	}
    	for(int i = 1; i <= n; i ++)
    		if(!tar::dep[i]) tar::tarjan(i);
    	top::build();
    	printf("%d", top::topo());
    }
    

    次短路


    数论

    gcd

    #include<bits/stdc++.h>
    using namespace std;
    int gcd(int a, int b)
    {
    	if(b == 0) return a;
    	return gcd(b, a % b);
    }
    int m, n;
    int main()
    {
    	scanf("%d%d", &n, &m);
    	printf("%d", gcd(n, m));
    }
    

    exgcd

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll read()
    {
    	char c = getchar(), last = ' ';
    	ll ans = 0;
    	while(c < '0' || c > '9') last = c, c = getchar();
    	while(c >= '0' && c <= '9') ans = ans * 10 + c - '0', c = getchar();
    	if(last == '-') ans = -ans;
    	return ans;
    }
    ll gcd(ll a, ll b)
    {
    	if(b == 0) return a;
    	return gcd(b, a % b);
    }
    void exgcd(ll a, ll b, ll &x, ll &y)
    {
    	if(b == 0)
    	{
    		x = 1;
    		y = 0;
    		return;
    	}
    	ll p;
    	exgcd(b, a % b, x, y);
    	p = x;
    	x = y;
    	y = p - y * (a / b);
    	return;
    }
    int t;
    ll a, b, c, d;
    int main()
    {
    	ll t = read();
    	while(t --)
    	{
    		a = read(), b = read(), c = read();
    		ll x = 0, y = 0, dx, dy, l, r, s;
    		d = gcd(a, b);
    		if(c % d != 0) 
    		{
    			printf("-1
    ");
    			continue;
    		}
    		a /= d, b /= d, c /= d;
    		exgcd(a, b, x, y);
    		x *= c, y *= c;
    		dx = b, dy = a;
    		//printf("%lld %lld
    ", dx, dy);
    		l = ll(double(ceil(1.0 * (-x + 1) / (1.0 * dx))));
    		r = ll(double(floor(1.0 * (y - 1) / (1.0 * dy))));
    		//l = ll((-x + 1) / dx);
    		//r = ll((y - 1) / dy);
    		if(l > r) 
    		{
    			printf("%lld %lld
    ", x + l * dx, y - r * dy);
    		}
    		else 
    		{
    			printf("%lld %lld %lld %lld %lld
    ", r - l + 1, x + l * dx, y - r * dy, x + r * dx, y - l * dy);
    		}
    	}
    }
    

    乘法逆元(递推)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 3000005;
    ll n, p;
    ll inv[N];
    int main()
    {
    	scanf("%lld%lld", &n, &p);
    	inv[1] = 1;
    	for(int i = 2; i <= n; i ++)
    		inv[i] = ((-(p / i) * inv[p % i]) % p + p) % p;
    	for(int i = 1; i <= n; i ++) printf("%lld
    ", inv[i]);
    }
    

    乘法逆元((a^{p-2})

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 3000005;
    ll n, p;
    ll qpow(ll a, ll b)
    {
    	ll ans = 1;
    	while(b)
    	{
    		if(b & 1) ans = ans * a % p;
    		a = a * a % p;
    		b >>= 1;
    	}
    	return ans;
    }
    ll inv[N];
    int main()
    {
    	scanf("%lld%lld", &n, &p);
    	printf("%lld", qpow(n, p - 2));
    }
    

    裴蜀定理

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int n, ans;
    int gcd(int a, int b)
    {
    	if(b == 0) return a;
    	return gcd(b, a % b);
    }
    int main()
    {
    	scanf("%d", &n);
    	scanf("%d", &ans);
    	for(int i = 1, x; i < n; i ++)
    	{
    		scanf("%d", &x);
    		ans = gcd(ans, abs(x));
    	}
    	printf("%d", ans);
    }
    

    矩阵快速幂

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 105;
    const ll mod = 1e9 + 7;
    ll n, k;
    struct martix
    {
    	ll a[N][N];
    	martix(){memset(a, 0, sizeof(a));}
    	void clear()
    	{
    		for(int i = 1; i <= n; i ++) a[i][i] = 1;
    	}
    }m;
    martix cheng(martix a, martix b)
    {
    	martix c;
    	for(int k = 1; k <= n; k ++)
    		for(int i = 1; i <= n; i ++)
    			for(int j = 1; j <= n; j ++)
    			c.a[i][j] = (c.a[i][j] + 1ll * a.a[i][k] * b.a[k][j] + mod % mod) % mod;
    	return c;	
    }
    martix qpow(martix a, ll b)
    {
    	martix ans;
    	ans.clear();
    	while(b)
    	{
    		if(b & 1) ans = cheng(ans, a);
    		a = cheng(a, a);
    		b >>= 1;
    	}
    	return ans;
    }
    int main()
    {
    	scanf("%lld%lld", &n, &k);
    	
    	for(int i = 1; i <= n; i ++)
    		for(int j = 1; j <= n; j ++)
    			scanf("%lld", &m.a[i][j]);
    	martix ans = qpow(m, k);
    	for(int i = 1; i <= n; i ++)
    	{
    		for(int j = 1; j <= n; j ++) 
    			printf("%lld ", ans.a[i][j]);
    		printf("
    ");
    	}
    }
    

    矩阵加速(数列)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 105;
    const ll mod = 1e9 + 7;
    ll n, k;
    struct martix
    {
    	ll a[N][N];
    	martix(){memset(a, 0, sizeof(a));}
    	void clear()
    	{
    		for(int i = 1; i <= 3; i ++) a[i][i] = 1;
    	}
    }m, t;
    martix cheng(martix a, martix b)
    {
    	martix c;
    	for(int k = 1; k <= 3; k ++)
    		for(int i = 1; i <= 3; i ++)
    			for(int j = 1; j <= 3; j ++)
    			c.a[i][j] = (c.a[i][j] + 1ll * a.a[i][k] * b.a[k][j] + mod % mod) % mod;
    	return c;	
    }
    martix qpow(martix a, ll b)
    {
    	martix ans;
    	ans.clear();
    	while(b)
    	{
    		if(b & 1) ans = cheng(ans, a);
    		a = cheng(a, a);
    		b >>= 1;
    	}
    	return ans;
    }
    int T;
    int main()
    {
    	scanf("%d", &T);
    	while(T --)
    	{
    		scanf("%lld", &n);
    		m.a[1][1] = m.a[1][2] = m.a[1][3] = 1;
    		t.a[1][1] = t.a[1][2] = t.a[2][3] = t.a[3][1] = 1;
    		t.a[1][3] = t.a[2][1] = t.a[2][2] = t.a[3][2] = t.a[3][3]= 0;
    		martix ans = qpow(t, n - 1);
    		martix qwq;
    		for(int k = 1; k <= 3; k ++) 
    			for(int i = 1; i <= 1; i ++)
    				for(int j = 1; j <= 3; j ++)
    					qwq.a[i][j] = (qwq.a[i][j] + (1ll * m.a[i][k] * ans.a[k][j] + mod) % mod) % mod;
    		printf("%lld
    ", qwq.a[1][3]);
    	}
    	
    }
    
  • 相关阅读:
    阻止事件的默认行为,例如click <a>后的跳转~
    阻止事件冒泡
    IE67不兼容display:inline-block,CSS hack解决
    IE678不兼容CSS3 user-select:none(不可复制功能),需要JS解决
    JS数组常用方法总结
    json 只能用 for-in 遍历
    用实例的方式去理解storm的并发度
    OpenLDAP 搭建入门
    kafka api的基本使用
    kafka基本介绍
  • 原文地址:https://www.cnblogs.com/lcezych/p/13916100.html
Copyright © 2011-2022 走看看