zoukankan      html  css  js  c++  java
  • BZOJ1202: [HNOI2005]狡猾的商人

    1202: [HNOI2005]狡猾的商人

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 4198  Solved: 2026
    [Submit][Status][Discuss]

    Description

    刁 姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的。账本上记录了n个月以来的收入情况,其中第i 个月的收入额为Ai(i=1,2,3...n-1,n), 。当 Ai大于0时表示这个月盈利Ai 元,当 Ai小于0时表示这个月亏损Ai 元。所谓一段时间内的总收入,就是这段时间内每个月的收入额的总和。 刁姹的任务是秘密进行的,为了调查商人的账本,她只好跑到商人那里打工。她趁商人不在时去偷看账本,可是她无法将账本偷出来,每次偷看账本时她都只能看某 段时间内账本上记录的收入情况,并且她只能记住这段时间内的总收入。 现在,刁姹总共偷看了m次账本,当然也就记住了m段时间内的总收入,你的任务是根据记住的这些信息来判断账本是不是假的。

    Input

    第 一行为一个正整数w,其中w < 100,表示有w组数据,即w个账本,需要你判断。每组数据的第一行为两个正整数n和m,其中n < 100,m < 1000,分别表示对应的账本记录了多少个月的收入情况以及偷看了多少次账本。接下来的m行表示刁姹偷看m次账本后记住的m条信息,每条信息占一行,有三 个整数s,t和v,表示从第s个月到第t个月(包含第t个月)的总收入为v,这里假设s总是小于等于t。

    Output

    包含w行,每行是true或false,其中第i行为true当且仅当第i组数据,即第i个账本不是假的;第i行为false当且仅当第i组数据,即第i个账本是假的。

    Sample Input

    2
    3 3
    1 2 10
    1 3 -5
    3 3 -15
    5 3
    1 5 100
    3 5 50
    1 2 51

    Sample Output

    true
    false

    HINT

    Source

    【题解】

    一眼并查集,而眼部分和->前缀和常见套路。

    对于Σl..r = w

    拆成pre[r] - pre[l - 1]

    其中pre[i] = num[1] + num[2] + ... + num[i - 1] + num[i]

    用加权并查集维护前缀和

    即若fa[f1] = f2, 则pre[f2] - pre[f1] = val[cnt1]

    val[i]表示i到他父亲的权重

    推一推式子就能维护了

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <algorithm>
     6 #include <queue>
     7 #include <vector>
     8 #define min(a, b) ((a) < (b) ? (a) : (b))
     9 #define max(a, b) ((a) > (b) ? (a) : (b))
    10 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
    11 inline void swap(int &a, int &b)
    12 {
    13     int tmp = a;a = b;b = tmp;
    14 }
    15 inline void read(int &x)
    16 {
    17     x = 0;char ch = getchar(), c = ch;
    18     while(ch < '0' || ch > '9') c = ch, ch = getchar();
    19     while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
    20     if(c == '-') x = -x;
    21 }
    22 
    23 const int INF = 0x3f3f3f3f;
    24 const int MAXN = 100 + 10;
    25 
    26 int fa[MAXN], val[MAXN], n, m;
    27 
    28 int find(int x)
    29 {
    30     if(x == fa[x]) return x;
    31     int f = find(fa[x]);
    32     val[x] += val[fa[x]];
    33     fa[x] = f;
    34     return f;
    35 }
    36 
    37 int main()
    38 {
    39     int t;read(t);
    40     for(;t;--t)
    41     {
    42         read(n), read(m);
    43         for(register int i = 0;i <= n;++ i) fa[i] = i, val[i] = 0;
    44         for(register int i = 1;i <= m;++ i)
    45         {
    46             int l,r,w;
    47             read(l), read(r), read(w);
    48             int f1 = find(l - 1), f2 = find(r);
    49             if(f1 != f2)
    50             {
    51                 fa[f1] = f2;
    52                 val[f1] = w + val[r] - val[l - 1];
    53             }
    54             else
    55             {
    56                 if(val[l - 1]  - val[r] != w)
    57                 {
    58                     printf("false
    ");
    59                     break;
    60                 }
    61             }
    62             if(i == m) printf("true
    ");
    63         }
    64     }
    65     return 0;
    66 } 
    BZOJ1202
  • 相关阅读:
    指针的学习
    (转)c & c++内存分配
    C++实现String
    c& c++笔试题
    appium python api收集
    公司python入职培训流程
    app端性能测试笔记
    h5 测试关注点
    robot framework 牛刀一试
    adb 安装apk 报错:Failure [INSTALL_FAILED_INVALID_URI]
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/7979738.html
Copyright © 2011-2022 走看看