zoukankan      html  css  js  c++  java
  • 华中校赛 14th

    https://www.nowcoder.com/acm/contest/106#question

    A

    分类讨论

    #include<bits/stdc++.h>
    using namespace std ;
    #define LL long long
    int a[100010] ;
    int d[100010] ;
    vector< int > v[100010] ;
    void dfs( int id , int fa , int c ){
        d[id] = c ;
        for( int i = 0 ; i < v[id].size() ; i++ ){
            if( v[id][i] == fa ) continue ;
            dfs( v[id][i] , id , 3 - c ) ;
        }
    }
    int main(){
        int T ;
        cin >> T ;
        while( T-- ){
              int n ;
              scanf( "%d" , &n ) ;
              for( int i = 1 ; i <= n ; i++ )
                  v[i].clear() ;
              for( int i = 1 ; i <= n - 1 ; i++ ){
                  int a , b ;
                  scanf( "%d%d" , &a , &b ) ;
                  v[a].push_back( b ) ;
                  v[b].push_back( a ) ;
              }
              dfs( 1 , 0 , 1 ) ;
              LL b , w ;
              b = 0 ; w = 0 ;
              for( int i = 1 ; i <= n ; i++ )
                  if ( d[i] == 1 ) b++ ;
                  else w++ ;
              LL ans = 0 ;
              if ( n & 1 ) { ans = 2 * ( b * b * w + w * w * b ) ; }
              else{ ans = b * b * b + w * w * w + b * b * w + w * w * b ; }
              printf( "%lld
    " , ans ) ;
        }
        return 0 ;
    }
    View Code

    B

    等比数列

    #include<bits/stdc++.h>
    using namespace std ;
    #define LL long long
    char s[100010] ;
    const LL mod = 1e9 + 7 ;
    LL two[100010] ;
    LL pow_mod( LL a , LL b ){
       a %= mod ;
       LL ans = 1 ;
       while( b ){
             if ( b & 1 ) { ans *= a ; ans %= mod ; }
             a *= a ; a %= mod ; b >>= 1 ;
       }
       return ans ;
    }
    LL inv_mod( LL x ){
       return pow_mod( x , mod - 2 ) ;
    }
    int main(){
        int k ;
        cin >> k ;
        scanf( "%s" , s ) ;
        two[0] = 1 ;
        for( int i = 1 ; i <= 100000 ; i++ ){
            two[i] = two[i - 1] * 2 ;
            two[i] %= mod ;
        }
        LL ans = 0 ;
        int len = strlen( s ) ;
        for( int i = 0 ; i < len ; i++ ){
            if ( s[i] == '0' || s[i] == '5' ){
                ans += two[i] ; ans %= mod ;
            }
        }
        LL q = two[len] ;
        if ( q == 1 ) { ans *= k ; ans %= mod ; }
        else{
             LL res = pow_mod( q , k ) ;
             res-- ; if ( res < 0 ) res += mod ;
             ans *= res ; ans %= mod ;
             q-- ; if ( q < 0 ) q += mod ;
             ans *= inv_mod( q ) ; ans %= mod ;
        }
        cout << ans << endl ;
        return 0 ;
    }
    View Code

    C

    并查集 (不带子树转移版)

    有四种操作

    1 u v 合并u,v所在的并查集

    2 u  将u从其所在的并查集中分离出来

    3 u 询问u所在并查集的大小

    4 u v 询问u,v是否在一个并查集内

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define ull unsigned long long
    #define pii pair<int, int>
    #define pb push_back
    #define mk make_pair
    #define fi first
    #define se second
    #define ALL(A) A.begin(), A.end()
    #define sqr(x) ((x)*(x))
    #define sc(x) scanf("%d", &x)
    #define pr(x) printf(">>>"#x":%d
    ", x)
    #define fastio ios::sync_with_stdio(0),cin.tie(0)
    #define frein freopen("in.txt", "r", stdin)
    #define freout freopen("out.txt", "w", stdout)
    #define debug cout<<">>>STOP"<<endl
    template<class T> T gcd(T a, T b)
    {
            if (!b)
            {
                    return a;
            }
            return gcd(b, a % b);
    }
    const int maxn = 2e5 + 10;
    int par[maxn], hs[maxn];
    int sz[maxn];
    int cnt;
    void init(int n)
    {
            for (int i = 0; i <= n; i++)
            {
                    par[i] = i, hs[i] = i, sz[i] = 1;
            }
    }
    int find(int x)
    {
            return par[x] == x ? x : par[x] = find(par[x]);
    }
    void unite(int x, int y)
    {
            x = find(x);
            y = find(y);
            if (x != y)
            {
                    par[x] = y, sz[y] += sz[x];
            }
    }
    void del(int x)
    {
            sz[find(hs[x])]--;
            hs[x] = ++cnt;
    }
    int main()
    {
            int T, kase = 1;
            sc(T);
            while (T--)
            {
                    printf("Case #%d:
    ", kase++);
                    int n, q;
                    sc(n);
                    sc(q);
                    init(n + q);
                    cnt = n;
                    for (int i = 0; i < q; i++)
                    {
                            int op;
                            sc(op);
                            if (op == 1)
                            {
                                    int u, v;
                                    sc(u);
                                    sc(v);
                                    unite(hs[u], hs[v]);
                            }
                            else if (op == 2)
                            {
                                    int u;
                                    sc(u);
                                    del(u);
                            }
                            else if (op == 3)
                            {
                                    int u;
                                    sc(u);
                                    int ans = sz[find(hs[u])];
                                    printf("%d
    ", ans);
                            }
                            else
                            {
                                    int u, v;
                                    sc(u);
                                    sc(v);
                                    if (find(hs[u]) == find(hs[v]))
                                    {
                                            printf("YES
    ");
                                    }
                                    else
                                    {
                                            printf("NO
    ");
                                    }
                            }
                    }
            }
            return 0;
    }
    View Code

    F

    冒泡排序变种

    #include<bits/stdc++.h>
    typedef long long ll;
    using namespace std;
    const ll mod = 1e9 + 9;
    int num[100005];
    int number[100005];
    int visit[100005];
    vector<int> now[100005];
    int pop = 0;
    int ans[100005];
    int main()
    {
            int n;
            int k;
            cin >> n >> k;
            int cur = 0;
            for (int i = 1; i <= n; i++)
            {
                    scanf("%d", &num[i]);
                    ans[i] = num[i];
            }
            sort(ans + 1, ans + 1 + n);
            if (k == 0)
            {
                    for (int i = 1; i <= n; i++)
                    {
                            if (num[i] != ans[i])
                            {
                                    cout << i << endl;
                                    return 0;
                            }
                    }
                    cout << -1 << endl;
                    return 0;
            }
            for (int i = 1; i <= n; i++)
            {
                    if (visit[i])
                    {
                            continue;
                    }
                    ++pop;
                    cur = 0;
                    for (int j = i; j <= n; j += k)
                    {
                            if (!visit[j])
                            {
                                    now[pop].push_back(num[j]);
                                    //cout<<num[j]<<" "<<j<<" ";
                            }
                    }
                    //cout<<endl;
                    sort(now[pop].begin(), now[pop].end());
                    for (int j = i; j <= n; j += k)
                    {
                            if (!visit[j])
                            {
                                    number[j] = now[pop][cur++];
                                    visit[j] = 1;
                            }
                    }
            }
            for (int i = 1; i <= n; i++)
            {
                    if (number[i] != ans[i])
                    {
                            cout << i << endl;
                            return 0;
                    }
            }
            cout << -1 << endl;
            return 0;
    }
    View Code

    G

    反推是否符合垂心 重心 内心 外心

    x=[0,0,0,0];
    y=[0,0,0,0];
    def dOt(x0,y0,x1,y1):
        return x0*x1+y0*y1;
     
    def cRoss(x0,y0,x1,y1):
        return x0*y1-x1*y0;
     
    def lEnth2(x,y):
        return x*x+y*y;
     
    def check0():
        n=[0,0,0];
        for i in range(3):
            n[i]=cRoss(x[(i+1)%3]-x[i],y[(i+1)%3]-y[i],x[3]-x[i],y[3]-y[i]);
        if (n[0]<0 and n[1]<0 and n[2]<0) or (0<n[0] and 0<n[1] and 0<n[2]):
            return 1;
        else:
            return 0;
     
    def check1():
        for i in range(3):
            if dOt(x[i]-x[3],y[i]-y[3],x[(i+2)%3]-x[(i+1)%3],y[(i+2)%3]-y[(i+1)%3])!=0:
                return 0;
        return 1
     
    def check2():
        n=[0,0];
        for i in range(3):
            n[0]=abs(cRoss(x[(i+1)%3]-x[i],y[(i+1)%3]-y[i],x[3]-x[i],y[3]-y[i]));
            n[1]=abs(cRoss(x[(i+2)%3]-x[i],y[(i+2)%3]-y[i],x[3]-x[i],y[3]-y[i]));
            if n[0]!=n[1]:
                return 0;
        if check0()==1:
            return 1;
        else:
            return 0;
     
    def check3():
        s=[0,0,0];
        l=[0,0,0];
        for i in range(3):
            s[i]=abs(cRoss(x[i]-x[3],y[i]-y[3],x[(i+1)%3]-x[3],y[(i+1)%3]-y[3]));
            l[i]=lEnth2(x[(i+1)%3]-x[i],y[(i+1)%3]-y[i]);
        for i in range(3):
            if s[i]*s[i]*l[(i+1)%3]!=s[(i+1)%3]*s[(i+1)%3]*l[i]:
                return 0;
        if check0()==1:
            return 1;
        else:
            return 0;
     
    def check4():
        d=[0,0,0];
        for i in range(3):
            d[i]=lEnth2(x[i]-x[3],y[i]-y[3]);
        if d[0]!=d[1] or d[1]!=d[2] or d[2]!=d[0]:
            return 0;
        return 1
     
    for i in range(4):
        x[i],y[i]=map(int,input().split());
    if check1()==1 or check2()==1 or check3()==1 or check4()==1:
        print("Yes");
    else:
        print("No");
    View Code

    I

    单调队列 O(n)可以处理处每个点的贡献

    注意在push的时候一侧要是严格的 另一侧要是不严格的 比如先>= 后> 因为这样才是全部情况 如果全是严格则缺少情况 全是不严格则有重复情况

    (即一个区间应只有一个最大值最小值有贡献 如果有多个最大值最小值也只能算一次)

    #include<bits/stdc++.h>
    using namespace std;
    #define LL long long
    const int maxn = 1000000 + 50;
    int a[maxn], l[maxn], r[maxn];
    inline void scan(int &a)
    {
            a = 0;
            char c;
            while (c = getchar(), !isdigit(c));
            a = c - '0';
            while (c = getchar(), isdigit(c))
            {
                    a = a * 10 + c - '0';
            }
    }
    int main()
    {
            int n;
            while (scanf("%d", &n) != EOF)
            {
                    LL res = 0;
                    for (int i = 1; i <= n; i++)
                    {
                            scanf("%d", &a[i]);
                    }
                    for (int i = 1; i <= n; i++)
                    {
                            l[i] = r[i] = i;
                    }
                    for (int i = 2; i <= n; i++)
                    {
                            int cur = i;
                            while (cur > 1 && a[i] >= a[cur - 1])
                            {
                                    cur = l[cur - 1];
                            }
                            l[i] = cur;
                    }
                    for (int i = n - 1; i >= 1; i--)
                    {
                            int cur = i;
                            while (cur < n && a[i] > a[cur + 1])
                            {
                                    cur = r[cur + 1];
                            }
                            r[i] = cur;
                    }
                    for (int i = 1; i <= n; i++)
                    {
                            res += (LL)a[i] * (LL)(i - l[i] + 1) * (LL)(r[i] - i + 1);
                    }
                    for (int i = 1; i <= n; i++)
                    {
                            l[i] = r[i] = i;
                    }
                    for (int i = 2; i <= n; i++)
                    {
                            int cur = i;
                            while (cur > 1 && a[i] <= a[cur - 1])
                            {
                                    cur = l[cur - 1];
                            }
                            l[i] = cur;
                    }
                    for (int i = n - 1; i >= 1; i--)
                    {
                            int cur = i;
                            while (cur < n && a[i] < a[cur + 1])
                            {
                                    cur = r[cur + 1];
                            }
                            r[i] = cur;
                    }
                    for (int i = 1; i <= n; i++)
                    {
                            res -= (LL)a[i] * (LL)(i - l[i] + 1) * (LL)(r[i] - i + 1);
                    }
                    printf("%lld
    ", res);
            }
            return 0;
    }
    View Code

    J

    BFS

    #include<bits/stdc++.h>
    typedef long long ll;
    using namespace std;
    const ll mod = 1e9 + 9;
    int dp[1000005];
    void init()
    {
            dp[1] = 1, dp[2] = 1;
            for (int i = 3; i <= 1000000; i++)
            {
                    dp[i] = dp[i - (i & (-i))] + 1;
            }
    }
    int visit[1000005];
    queue<pair<int, int> > que;
    int main()
    {
            init();
            int a, b;
            cin >> a >> b;
            int anser = INT_MAX;
            que.push(make_pair(a, 0));
            while (!que.empty())
            {
                    int now = que.front().first;
                    visit[now] = 1;
                    int cur = que.front().second;
                    //cout<<now<<" "<<cur<<endl;
                    que.pop();
                    if (now == b)
                    {
                            cout << cur << endl;
                            return 0;
                    }
                    if (!visit[now - 1])
                    {
                            que.push(make_pair(now - 1, cur + 1));
                            visit[now - 1] = 1;
                    }
                    if (!visit[now + 1])
                    {
                            que.push(make_pair(now + 1, cur + 1));
                            visit[now + 1] = 1;
                    }
                    if (!visit[now + dp[now]])
                    {
                            que.push(make_pair(now + dp[now], cur + 1));
                            visit[now + dp[now]] = 1;
                    }
                    if (!visit[now - dp[now]])
                    {
                            que.push(make_pair(now - dp[now], cur + 1));
                            visit[now - dp[now]] = 1;
                    }
            }
            return 0;
    }
    View Code

    K

    二分答案

    #include<bits/stdc++.h>
    using namespace std ;
    int a[100010] ;
    #define LL long long
    int main(){
        int n , k ;
        cin >> n >> k ;
        for( int i = 1 ; i <= n - 1 ; i++ )
            scanf( "%d" , &a[i] ) ;
        LL l , r ;
        l = 0 ; r = 1e11 ;
        while( l + 1 < r ){
              LL mid = ( l + r ) >> 1 ;
              LL sum = 0 ;
              int cnt = 1 ;
              for( int i = 1 ; i <= n - 1 ; i++ ){
                  if ( a[i] > mid ) { cnt += 0x3f3f3f3f ; break ; }
                  sum += a[i] ;
                  if ( sum > mid ){
                      cnt++ ; sum = a[i] ;
                  }
              }
              if ( cnt > k ) l = mid ;
              else r = mid ;
        }
        cout << r << endl ;
        return 0 ;
    }
    View Code

    L

    倒着搜索

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    const int maxn = 2e3 + 10;
    const int maxm = 1e5 + 10;
    struct coord
    {
            int x, y;
    } tmp, nxt;
    queue<coord>q;
    int T, m, res;
    int x[maxm], y[maxm], ans[maxn];
    int state[maxn][maxn];
    int dir[4][2] = {{0, -1}, {0, 1}, { -1, 0}, {1, 0}};
    void bfs(int x, int y)
    {
            state[tmp.x = x][tmp.y = y] = 2; //给所有大空地的地方打上标记 相当于并查集
            res--, q.push(tmp);  //剩下的数目-1 进行BFS
            while (!q.empty())
            {
                    tmp = q.front();
                    q.pop();
                    for (int i = 0; i < 4; i++)
                    {
                            nxt.x = tmp.x + dir[i][0]; //目标点的横纵坐标
                            nxt.y = tmp.y + dir[i][1];
                            if (nxt.x < 0 || nxt.x > 2000 || nxt.y < 0 || nxt.y > 2000) //如果这个点不符合条件
                            {
                                    continue;
                            }
                            if (state[nxt.x][nxt.y] != 0) //如果这个点是树
                            {
                                    continue;
                            }
                            state[nxt.x][nxt.y] = 2;
                            res--;
                            q.push(nxt);
                    }
            }
    }
    bool check(int x, int y)
    {
            for (int i = 0; i < 4; i++)
            {
                    int xx = x + dir[i][0], yy = y + dir[i][1];
                    if (xx < 0 || xx > 2000 || yy < 0 || yy > 2000)
                    {
                            continue;
                    }
                    if (state[xx][yy] == 2)
                    {
                            return 1;
                    }
            }
            return 0;
    }
    int main()
    {
            scanf("%d", &m);
            for (int i = 1; i <= m; i++)
            {
                    scanf("%d%d", &x[i], &y[i]);
                    x[i] += 1000, y[i] += 1000;  //避免负数 往右下移动1000
                    state[x[i]][y[i]] = 1;  //表示该坐标是树
            }
            res = 2001 * 2001 - m;  //减去2001*2001剩下的不是树的点
            bfs(0, 0);  //减去所有没有被树包围的点
            for (int i = m; i; i--)
            {
                    ans[i] = res++;
                    state[x[i]][y[i]] = 0;
                    if (check(x[i], y[i])) //如果这个树的四连通块有一个属于大空地 就把这个树连通的连通块全部BFS成大空地
                    {
                            bfs(x[i], y[i]);
                    }
            }
            for (int i = 1; i <= m; i++)
            {
                    printf("%d
    ", ans[i]);
            }
            return 0;
    }
    View Code
  • 相关阅读:
    ORA00911: 无效字符
    在创建外键约束时追加on delete cascade或on delete set null
    仿58同城下拉菜单
    经典SQL语句大全
    Substitution 使用方法 页面缓存时的局部刷新
    解决IE8开发人员工具无法使用的问题
    ASP.NET 页面缓存 @ OutputCache
    关于clientWidth、offsetWidth、clientHeight、offsetHeight的测试比较
    调用ThunderAgent 迅雷局域网版的开发
    仿58同城 tips 鼠标悬停提示 类似title、alt
  • 原文地址:https://www.cnblogs.com/Aragaki/p/8971940.html
Copyright © 2011-2022 走看看