zoukankan      html  css  js  c++  java
  • Subset Sums

    题意:

    给一长度为n的序列a[],给定m个大小为$k_i$的正整数的集合,集合内元素 $x_i≤n$ 且不重复。

    给定两种操作:

      1.输入x,y,对于所有的 $a(i)  (i ∈ Sx)$ 加上 y。

      2.输入x,求$sum_{i=1}^{k_x}{a(S_{x,i})}$

    解法:

    将集合分类,分为大于$sqrt n$的集合和小于$sqrt n$的集合。

    考虑4种情况:

    1.大于$sqrt n$的集合对小于$sqrt n$的集合的贡献。

    2.大于$sqrt n$的集合对大于$sqrt n$的集合的贡献。

    3.小于$sqrt n$的集合对大于$sqrt n$的集合的贡献。

    4.小于$sqrt n$的集合对小于$sqrt n$的集合的贡献。

    对于情况1,2,3我们只要记录对于所有集合有多少个大于$sqrt n$的集合和它有元素重合 且 算出重合多少个元素。

    对于情况 4 直接维护一个数组即可。

    总效率$O(n sqrt n)$

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <vector>
      5 #include <cmath>
      6 
      7 using namespace std;
      8 
      9 #define N 100010
     10 #define LL long long
     11 typedef pair<int,int> PII;
     12 #define fir first
     13 #define sec second
     14 #define SIZE 320
     15 
     16 int n,m,q;
     17 int siz[N],bblc[N],sblc[N],totb,tots;
     18 LL a[N],ans[N],add[N],addi[N];
     19 bool v[N];
     20 vector<int> c[N];
     21 vector<PII> g[N];
     22 
     23 int main()
     24 {
     25     while(~scanf("%d%d%d",&n,&m,&q))
     26     {
     27         for(int i=1;i<=n;i++) scanf("%I64d",&a[i]);
     28         //int SIZE = (int)sqrt(n+0.5);
     29         totb=tots=0;
     30         for(int i=1;i<=m;i++) g[i].clear();
     31         for(int i=1,k,x;i<=m;i++)
     32         {
     33             scanf("%d",&k);
     34             add[i]=0;
     35             siz[i]=k;
     36             if(k>=SIZE) bblc[++totb]=i;
     37             else sblc[++tots]=i;
     38             c[i].clear();
     39             ans[i]=0;
     40             while(k--)
     41             {
     42                 scanf("%d",&x);
     43                 c[i].push_back(x);
     44                 ans[i]+=a[x];
     45             }
     46         }
     47         for(int i=1,x;i<=totb;i++)
     48         {
     49             x=bblc[i];
     50             for(int j=0;j<siz[x];j++) v[c[x][j]]=1;
     51             for(int y=1;y<=m;y++)
     52             {
     53                 int tmp=0;
     54                 for(int k=0;k<siz[y];k++)
     55                     if(v[c[y][k]]) tmp++;
     56                 if(tmp)
     57                 {
     58                     if(siz[y]>=SIZE)
     59                         g[x].push_back(make_pair(y,tmp));
     60                     else
     61                         g[y].push_back(make_pair(x,tmp));
     62                 }
     63             }
     64             for(int j=0;j<siz[x];j++) v[c[x][j]]=0;
     65         }
     66         char ch;
     67         int x,y;
     68         while(q--)
     69         {
     70             while(ch=getchar(),ch!='?'&&ch!='+');
     71             scanf("%d",&x);
     72             if(ch=='?')
     73             {
     74                 if(siz[x]>=SIZE)
     75                 {
     76                     LL ansv=ans[x];
     77                     int nl=g[x].size();    //big->big
     78                     for(int i=0;i<nl;i++)
     79                         ansv+=add[g[x][i].fir]*(LL)g[x][i].sec;
     80                     printf("%I64d
    ",ansv);
     81                 }
     82                 else
     83                 {
     84                     LL ansv=ans[x];
     85                     int nl=g[x].size();
     86                     for(int i=0;i<nl;i++)    //big->small
     87                         ansv+=add[g[x][i].fir]*(LL)g[x][i].sec;
     88                     nl=c[x].size();            //small->small2
     89                     for(int i=0;i<nl;i++) ansv += addi[c[x][i]];
     90                     printf("%I64d
    ",ansv);
     91                 }
     92             }
     93             else
     94             {
     95                 scanf("%d",&y);
     96                 if(siz[x]>=SIZE)
     97                 {
     98                     add[x]+=(LL)y;    //big->small
     99                         //big->big
    100                 }
    101                 else
    102                 {
    103                     int nl=g[x].size();    //small->big
    104                     for(int i=0;i<nl;i++)
    105                         ans[g[x][i].fir] += y*(LL)g[x][i].sec;
    106                     nl=c[x].size();            //small->small1
    107                     for(int i=0;i<nl;i++) addi[c[x][i]] += (LL)y;
    108                 }
    109             }
    110         }
    111     }
    112     return 0;
    113 }
    View Code
  • 相关阅读:
    变量和数据类型
    Manager 多进程之间的数据共享
    多进程之间的数据传输 Pipe
    多进程
    消费者 生产者
    queue 队列优先级
    Python 最难的问题
    threading 多线程
    线程进程概述
    倒计时器 小玩意
  • 原文地址:https://www.cnblogs.com/lawyer/p/6503432.html
Copyright © 2011-2022 走看看