zoukankan      html  css  js  c++  java
  • 1019考试总结

    T1

    先将两个大数分开,很显然一个很小,一个是111....1这样的形式

    第一个直接暴力枚举,第二个考虑转化为(10^k-1)/9这样的形式,然后求 9 的逆元,注意 9 对于 3 没有逆元,特判

    #include <cstdio>
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    long long ksm(long long a,long long b,long long p)
    {
      long long res=1;
      while(b)
      {
        if(b&1) res=res*a%p;
        b>>=1;
        a=a*a%p;
      }
      return res;
    }
    
    string s;
    
    long long ans,ap,p[5000010];
    
    bool pr[5000010];
    
    int cnt;
    
    void init()
    {
      for(int i=2;i<=5000000;i++)
      {
        if(!pr[i])
        {
          p[++cnt]=i;
          for(int j=2;i*j<=5000000;j++)
          {
            pr[i*j]=1;
          }
        }
      }
    }
    
    long long work(long long len,long long p)
    {
      if(p==3) return len%3==0;
      return (ksm(10,len,p)-1+p)%p*ksm(9,p-2,p)%p==0;
    }
    
    int main()
    {
      //freopen("candy.in","r",stdin);
      //freopen("candy.out","r",stdout);
      init();
      cin>>s;
      for(int i=0;i<s.size();i++) ans+=s[i]-'0';
      ap=ans;
      for(long long i=1;i<=cnt;i++)
      {
        if(ans%p[i]==0||work(s.size(),p[i]))
        {
          ap=p[i];
          break;
        }
      }
      printf("%lld",ap);
    }
    

    T2

    大力dp,设dp[i][j][k]表示[i,j]对于k这个边界是否可行

    没有打过的原因是打了一个假的n^2实际n^4的记忆化,看过主定理发现并不是我所想的复杂度

    #include <cstdio>
    #include <vector>
    #include <cstring>
    
    using namespace std;
    
    int a[1010];
    
    bool con[1010][1010];
    
    bool f[510][510][510];
    
    bool vis[510][510][510];
    
    int n;
    
    int gcd(int a,int b)
    {
      while((a%=b)&&(b%=a));
      return a+b;
    }
    
    bool dfs(int l,int r,int now)
    {
      if(vis[l][r][now]) return f[l][r][now];
      vis[l][r][now]=1;
      if(l>r) return f[l][r][now]=1;
      if(l==r) return f[l][r][now]=con[l][now];
      for(int i=l;i<=r;i++)
        if(con[i][now]&&dfs(l,i-1,i)&&dfs(i+1,r,i))
          return f[l][r][now]=1;
      return f[l][r][now]=0;
    }
    
    void work()
    {
      memset(con,0,sizeof(con));
      memset(vis,0,sizeof(vis));
      memset(f,0,sizeof(f));
      for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
          if(gcd(a[i],a[j])!=1)
            con[i][j]=1;
      // for(int i=1;i<=n;i++)
      // {
      //   for(int j=1;j<=n;j++)
      //       printf("%d ",con[i][j]);
      //   printf("
    ");
      // }
      bool flag=0;
      for(int i=1;i<=n;i++) if(dfs(1,i-1,i)&&dfs(i+1,n,i))
      {
        printf("Yes
    ");
        return ;
      }
      printf("No
    ");
    }
    
    int main()
    {
      //freopen("tree.in","r",stdin);
      //freopen("tree.out","r",stdout);
      int t;
      scanf("%d",&t);
      while(t--)
      {
        memset(a,0,sizeof(a));
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        work();
      }
    }
    

    T3

    LNOI原题

    没a的原因是线段树在上传的时候没有更新(好像之前也出现过,这种东西还很难调,没有啥明确的可以指出是这个错误的

    直接考虑前缀化询问,然后离线就行

    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    
    struct Segment
    {
      long long val,tag;
    }tree[500010<<2];
    
    struct Edge
    {
      int to,next;
    }e[1000010];
    
    struct Query
    {
      int pos,id,pi;
      long long vf;
    }wq[1000010];
    
    int n,q;
    
    int num,head[1000010];
    
    int size[500010],fa[500010],son[500010],top[500010],p[500010],cnt,cnting;
    
    long long ans[500010];
    
    bool cmp(Query a,Query b)
    {
      return a.pos<b.pos;
    }
    
    void addedge(int a,int b)
    {
      e[++num].to=b;
      e[num].next=head[a];
      head[a]=num;
    }
    
    void pushdown(int u,int l,int r)
    {
      int mid=(l+r)>>1;
      tree[u<<1].tag+=tree[u].tag;
      tree[u<<1|1].tag+=tree[u].tag;
      tree[u<<1].val+=(long long)(mid-l+1)*tree[u].tag%201314;
      tree[u<<1|1].val+=(long long)(r-mid)*tree[u].tag%201314;
      tree[u].tag=0;
    }
    
    long long findtree(int u,int l,int r,int x,int y)
    {
      if(x<=l&&r<=y) return tree[u].val;
      if(tree[u].tag) pushdown(u,l,r);
      int mid=(l+r)>>1;
      long long ans=0;
      if(x<=mid) ans+=findtree(u<<1,l,mid,x,y);
      if(y>mid) ans+=findtree(u<<1|1,mid+1,r,x,y);
      return ans%201314;
    }
    
    void changetree(int u,int l,int r,int x,int y)
    {
      if(x<=l&&r<=y)
      {
        tree[u].val+=(r-l+1);
        tree[u].val%=201314;
        tree[u].tag++;
        tree[u].tag%=201314;
        return ;
      }
      if(tree[u].tag) pushdown(u,l,r);
      int mid=(l+r)>>1;
      if(x<=mid) changetree(u<<1,l,mid,x,y);
      if(y>mid) changetree(u<<1|1,mid+1,r,x,y);
      tree[u].val=(tree[u<<1].val+tree[u<<1|1].val)%201314;
    }
    
    void dfs1(int u)
    {
      size[u]=1;
      for(int i=head[u];i;i=e[i].next)
      {
        fa[e[i].to]=u;
        dfs1(e[i].to);
        size[u]+=size[e[i].to];
        if(size[e[i].to]>size[son[u]]) son[u]=e[i].to;
      }
    }
    
    void dfs2(int u,int t)
    {
      top[u]=t;
      p[u]=++cnting;
      if(!son[u]) return ;
      dfs2(son[u],t);
      for(int i=head[u];i;i=e[i].next)
      {
        if(e[i].to^son[u])
        {
          dfs2(e[i].to,e[i].to);
        }
      }
    }
    
    void change(int u)
    {
      while(u)
      {
        changetree(1,1,n,p[top[u]],p[u]);
        u=fa[top[u]];
      }
    }
    
    int query(int u)
    {
      long long res=0;
      while(u)
      {
        res+=findtree(1,1,n,p[top[u]],p[u]);
        res%=201314;
        u=fa[top[u]];
      }
      return res;
    }
    
    int main()
    {
      //freopen("elf.in","r",stdin);
      //freopen("elf.out","r",stdout);
      scanf("%d%d",&n,&q);
      for(int i=2;i<=n;i++)
      {
        int x;
        scanf("%d",&x);
        addedge(x,i);
      }
      for(int i=1;i<=q;i++)
      {
        int l,r,z;
        scanf("%d%d%d",&l,&r,&z);
        wq[++cnt].id=i;
        wq[cnt].pi=z;
        wq[cnt].pos=l-1;
        wq[cnt].vf=-1;
        wq[++cnt].id=i;
        wq[cnt].pi=z;
        wq[cnt].pos=r;
        wq[cnt].vf=1;
      }
      dfs1(1);
      dfs2(1,1);
      fa[1]=0;
      sort(wq+1,wq+cnt+1,cmp);
      int pl=1;
      while(wq[pl].pos==0&&pl<=cnt) pl++;
      for(int i=1;i<=n;i++)
      {
        change(i);
        while(wq[pl].pos==i&&pl<=cnt)
        {
          ans[wq[pl].id]+=wq[pl].vf*query(wq[pl].pi);
          ans[wq[pl].id]=((ans[wq[pl].id]%201314)+201314)%201314;
          pl++;
        }
      }
      for(int i=1;i<=q;i++) printf("%lld
    ",ans[i]);
    }
    
  • 相关阅读:
    131. Palindrome Partitioning
    130. Surrounded Regions
    129. Sum Root to Leaf Numbers
    128. Longest Consecutive Sequence
    125. Valid Palindrome
    124. Binary Tree Maximum Path Sum
    122. Best Time to Buy and Sell Stock II
    121. Best Time to Buy and Sell Stock
    120. Triangle
    119. Pascal's Triangle II
  • 原文地址:https://www.cnblogs.com/zzqdeco/p/13840977.html
Copyright © 2011-2022 走看看