xcpc自用板子

发布时间 2023-10-10 16:27:40作者: Beater_1117

Bellman-Ford最短路O(nm)

int INF = 0x3f3f3f3f;

 

struct edge { int from, to, cost; }edges[12405];

 

int n,m;

 

edge es[1000];

 

int d[2510];

 

 

void shortest_path(int s){

       for(int i=0;i<=n;i++){

              d[i]=INF;

       }

       d[s]=0;

       while(true){

              bool update=false;

              for(int i=0;i<m*2;i++){

              if(d[edges[i].from]!=INF&&d[edges[i].to]>d[edges[i].from]+edges[i].cost){

                            d[edges[i].to]=d[edges[i].from]+edges[i].cost;

                            update=true;

                     }

              }

              if(!update){

                     break;

              }

       }

}

 

       for(i=0;i<m;i++){

              cin>>u>>v>>w;

              edges[i*2].from=u;

              edges[i*2].to=v;

              edges[i*2].cost=w;

              edges[i*2+1].from=v;

              edges[i*2+1].to=u;

              edges[i*2+1].cost=w;

             

       }

       shortest_path(s);

       cout<<d[t]<<endl;

Floyd-Warshall最短路O(n^3)

int INF = 0x3f3f3f3f;

 

int d[2510][2510];

int n,m;

 

void warshall_floyd(){

       for(int k=0;k<=n;k++){

              for(int i=0;i<=n;i++){

                     for(int j=0;j<=n;j++){

                            d[i][j]=min(d[i][j],d[i][k]+d[k][j]);

                     }

              }

       }

}

 

       for(i=0;i<=n;i++){

              for(j=i+1;j<=n;j++){

                     d[i][j]=INF;

                     d[j][i]=INF;

              }

       }

       for(i=0;i<m;i++){

              cin>>u>>v>>w;

              d[u][v]=w;

              d[v][u]=w;

       }

       warshall_floyd();

       cout<<d[s][t]<<endl;

gcdO(log a)

int gcd(int a,int b){

       if(b==0) return a;

       return gcd(b,a%b);

}

mod_powO(log n)

ll mod_pow(ll x,ll n,ll mod){

       if(n==0) return 1;

       ll res=mod_pow(x*x%mod,n/2,mod);

       if(n&1) res=res*x%mod;

       return res;

}

STL

 

//vector容器

       vector<pair<ll,ll>> a;

       for(int i=1;i<=n;i++){

              ll c,b;

              cin>>c;

              b=i;

              a.push_back(make_pair(c,b));

       }

       sort(a.begin(),a.end());

       for(auto p:a){

              //p为a数组的值

       }

       //

       vector <vector<int >> res(k+1);//res[k+1][]

       for(int i=1;i<=n;i++){

              cin>>a[i];

              res[a[i]].push_back(i);

       }

       for(int i=0;i<res.size();i++){

              cout<<res[i]<<endl;

       }

       res[i].empty()//true为空,false为非空

       //

       vector <string > s;

       string str;

       cin>>str;

       s.push_back(str);

      

 

//map容器(可做桶用

       map<string,bool> s1;

       string str;

       cin>>str;

       s1[str]=1;

 

 

 

 

 

 

 

并查集

const int max_N=1e5+7;

 

int par[max_N];

int rank[max_N];

int value[max_N];

//初始化 max_N个元素

void init(int n){

       if(n==max_N) n--;

       for(int i=0;i<=n;i++){

              par[i]=i;

              rank[i]=0;

              value[i]=1;

       }

}

//查询树的根

int find(int x){

       if(par[x]==x){

              return x;

       }else{

              return par[x]=find(par[x]);

       }

}

//合并x和y所属的集合

void unite(int x,int y){

       x=find(x);

       y=find(y);

       if(x==y) return ;

       if(rank[x]<rank[y]){

              par[x]=y;

              value[y]+=value[x];

       }else{

              par[y]=x;

              value[x]+=value[y];

              if(rank[x]==rank[y]) rank[x]++;

       }

}

//判断x和y是否属于同一个集合

bool same(int x,int y){

       return find(x)==find(y);

}

 

 

查找子串find()

std::string s = "This is a sample string. Sample strings are useful for samples.";

std::string str = "sample";

 

size_t pos = s.find(str);

int count = 0;

 

while (pos != std::string::npos) {

    count++;

    pos = s.find(str, pos + 1);

}

二维差分

// 给以(x1, y1)为左上角,(x2, y2)为右下角的子矩阵中的所有元素加上c

void add(int x1, int y1, int x2, int y2, int c)

{

    f[x1][y1] += c;

    f[x2 + 1][y1] -= c;

    f[x1][y2 + 1] -= c;

    f[x2 + 1][y2 + 1] += c;

}

 

 

高精度

const int LEN = 1004;

 

void clear(int a[]) {

  for (int i = 0; i < LEN; ++i) a[i] = 0;

}

 

void read(int a[]) {

  static char s[LEN + 1];

  scanf("%s", s);

 

  clear(a);

 

  int len = strlen(s);

  // 如上所述,反转

  for (int i = 0; i < len; ++i) a[len - i - 1] = s[i] - '0';

  // s[i] - '0' 就是 s[i] 所表示的数码

  // 有些同学可能更习惯用 ord(s[i]) - ord('0') 的方式理解

}

 

void print(int a[]) {

  int i;

  for (i = LEN - 1; i >= 1; --i)

    if (a[i] != 0) break;

  for (; i >= 0; --i) putchar(a[i] + '0');

  putchar('\n');

}

 

void add(int a[], int b[], int c[]) {

  clear(c);

 

  // 高精度实现中,一般令数组的最大长度 LEN 比可能的输入大一些

  // 然后略去末尾的几次循环,这样一来可以省去不少边界情况的处理

  // 因为实际输入不会超过 1000 位,故在此循环到 LEN - 1 = 1003 已经足够

  for (int i = 0; i < LEN - 1; ++i) {

    // 将相应位上的数码相加

    c[i] += a[i] + b[i];

    if (c[i] >= 10) {

      // 进位

      c[i + 1] += 1;

      c[i] -= 10;

    }

  }

}

 

void sub(int a[], int b[], int c[]) {

  clear(c);

 

  for (int i = 0; i < LEN - 1; ++i) {

    // 逐位相减

    c[i] += a[i] - b[i];

    if (c[i] < 0) {

      // 借位

      c[i + 1] -= 1;

      c[i] += 10;

    }

  }

}

 

void mul_short(int a[], int b, int c[]) {

  clear(c);

 

  for (int i = 0; i < LEN - 1; ++i) {

    // 直接把 a 的第 i 位数码乘以乘数,加入结果

    c[i] += a[i] * b;

 

    if (c[i] >= 10) {

      // 处理进位

      // c[i] / 10 即除法的商数成为进位的增量值

      c[i + 1] += c[i] / 10;

      // 而 c[i] % 10 即除法的余数成为在当前位留下的值

      c[i] %= 10;

    }

  }

}

 

void mul(int a[], int b[], int c[]) {

  clear(c);

 

  for (int i = 0; i < LEN - 1; ++i) {

    // 这里直接计算结果中的从低到高第 i 位,且一并处理了进位

    // 第 i 次循环为 c[i] 加上了所有满足 p + q = i 的 a[p] 与 b[q] 的乘积之和

    // 这样做的效果和直接进行上图的运算最后求和是一样的,只是更加简短的一种实现方式

    for (int j = 0; j <= i; ++j) c[i] += a[j] * b[i - j];

 

    if (c[i] >= 10) {

      c[i + 1] += c[i] / 10;

      c[i] %= 10;

    }

  }

}

 

// 被除数 a 以下标 last_dg 为最低位,是否可以再减去除数 b 而保持非负

// len 是除数 b 的长度,避免反复计算

bool greater_eq(int a[], int b[], int last_dg, int len) {

  // 有可能被除数剩余的部分比除数长,这个情况下最多多出 1 位,故如此判断即可

  if (a[last_dg + len] != 0) return true;

  // 从高位到低位,逐位比较

  for (int i = len - 1; i >= 0; --i) {

    if (a[last_dg + i] > b[i]) return true;

    if (a[last_dg + i] < b[i]) return false;

  }

  // 相等的情形下也是可行的

  return true;

}

 

void div(int a[], int b[], int c[], int d[]) {

  clear(c);

  clear(d);

 

  int la, lb;

  for (la = LEN - 1; la > 0; --la)

    if (a[la - 1] != 0) break;

  for (lb = LEN - 1; lb > 0; --lb)

    if (b[lb - 1] != 0) break;

  if (lb == 0) {

    puts("> <");

    return;

  }  // 除数不能为零

 

  // c 是商

  // d 是被除数的剩余部分,算法结束后自然成为余数

  for (int i = 0; i < la; ++i) d[i] = a[i];

  for (int i = la - lb; i >= 0; --i) {

    // 计算商的第 i 位

    while (greater_eq(d, b, i, lb)) {

      // 若可以减,则减

      // 这一段是一个高精度减法

      for (int j = 0; j < lb; ++j) {

        d[i + j] -= b[j];

        if (d[i + j] < 0) {

          d[i + j + 1] -= 1;

          d[i + j] += 10;

        }

      }

      // 使商的这一位增加 1

      c[i] += 1;

      // 返回循环开头,重新检查

    }

  }

}

 

 

 

 

 

 

 

 

 

树上dp

#include <bits/stdc++.h>

using namespace std ;

const int max_N=2e5+7;

const int INF = 0x3f3f3f3f;

typedef long long ll;

 

vector<int> g[max_N];

ll dp[max_N];

 

void dfs(int u,int fa){

       if(g[u].size()==1&&u-1){

              dp[u]=1;

       }

       for(auto v : g[u]){

              if(v==fa){

                     continue ;

              }

              dfs(v,u);

              dp[u]+=dp[v];

       }

}

 

void solve(){

       int n;

       cin>>n;

       for(int i=1;i<=n;i++){

              g[i].clear();

              dp[i]=0;

       }

       for(int i=1;i<n;i++){

              int a,b;

              cin>>a>>b;

              g[a].push_back(b);

              g[b].push_back(a);

       }

       dfs(1,0);

       int q;

       cin>>q;

       for(int i=1;i<=q;i++){

              int x,y;

              cin>>x>>y;

              cout<<dp[x]*dp[y]<<endl;

       }

}

 

int main(){

       int t;

      

       cin>>t;

       while(t--){

              solve();

       }

      

       return 0;

}

 

 

 

 

位运算符

0&0=0;

0&1=0;

1&0=0;

1&1=1;

//全1出1

0|0=0;

0|1=1;

1|0=1;

1|1=1;

//有1出1

0^0=0;

0^1=1;

1^0=1;

1^1=0;

//一样出0,不一样出1

 

 

 

 

 

 

 

 

 

 

逆元(除数取模)

//拓展欧几里得

 

ll exgcd(ll a, ll b, ll &x, ll &y)// 拓欧

{

    if (b == 0)

    {

        x = 1;

        y = 0;

        return a;

    }

    ll d = exgcd(b, a % b, y, x);

    y -= (a / b) * x;

    return d;

}

ll inv(ll a, ll p)

{

    ll x, y;

    if (exgcd(a, p, x, y) != 1) // 无解的情形

        return -1;

    return (x % p + p) % p;

}

 

//inv(a,p)就是取模p意义下的1/a;

 

 

//费马小定理

inline ll qpow(ll a, ll n, ll p)// 快速幂

{

    ll ans = 1;

    while (n)

    {

        if (n & 1)

            ans = ans % p * a % p;

        a = a % p * a % p;

        n >>= 1;

    }

    return ans;

}

inline ll inv(ll a, ll p)

{

    return qpow(a, p - 2, p);

}

三维bfs

char g[max_N][max_N][max_N];

 

const int   dx[]={0,0,0,0,-1,1},

            dy[]={0,0,-1,1,0,0},

            dz[]={-1,1,0,0,0,0};

struct node

{

    int x,y,z;

};

int l,r,c;

queue<node>q;

int d[max_N][max_N][max_N];

int bfs(node st){

    while(!q.empty()){

        q.pop();

    }

    q.push(st);

    d[st.x][st.y][st.z]=0;

    while(!q.empty()){

        node t=q.front();

        q.pop();

        g[t.x][t.y][t.z]='#';

        for(int i=0;i<6;i++){

            int x=t.x+dx[i],y=t.y+dy[i],z=t.z+dz[i];

            if(x<0||x>=l||y<0||y>=r||z<0||z>=c){

                continue;

            }

            if(g[x][y][z]=='#'){

                continue;

            }

            d[x][y][z]=d[t.x][t.y][t.z]+1;

            if(g[x][y][z]=='E'){

                return d[x][y][z];

            }

            g[x][y][z]='#';

            node tt;

            tt.x=x,tt.y=y,tt.z=z;

            q.push(tt);

        }

    }

    return 0;

}

快速幂

#include <iostream>

long long Quick_Power(long long x,long long n)

{

    if(n==0)

    {

        return 1;

    }

    else if(n%2==1)

    {

        return Quick_Power(x,n-1)*x;

    }

    else

    {

        long long tmp=Quick_Power(x,n/2);

        return tmp*tmp;

    }

}

using namespace std;

int main()

{

    long long x,n;

    cin>>x>>n;

    cout<<Quick_Power(x,n);

}

 

 

 

long long ksm(long long a, long long b)

{

    long long res = 1;

    while(b)

    {

        if(b & 1) 

            res = res * a % M;

            a = a * a % M;

            b >>= 1;

    }

    return res;

}