2017.5.26暴力赛解题报告

预计分数:T1:40AC+60TLE

     T2:40AC+60TLE

       T3:10AC+90TLE

     总分=90

实际分数:T1:100AC+0TLE

     T2:80AC+20TLE

       T3:20AC+80TLE

     总分=200

感想:数据水的一逼!!

题目实际难度:

  T1:提高/提高+

  T2:提高+

  T3:提高+/省选-

我眼中的难度
  T1:普及

  T2:普及-

  T3:入门难度

2039. 树的统计

★★   输入文件:counttree.in   输出文件:counttree.out   简单对比
时间限制:1 s  
内存限制:128 MB

【题目描述】

关于树的统计问题有多种多样的版本,这里你需要解决一个比较简单的问题:对于一棵包含N个节点的有根树,将所有点从1到N编号后,对于每一个节点v,统计出以v为根的子树中有多少个点的编号比v小。

【输入格式】

输入第一行包含一个整数N,以下N行每行包含一个整数,其中第i行的整数表示编号为i的节点的父亲节点的编号,根的父亲节点编号为0。

【输出格式】

输出包含N行,其中第i行给出编号为i的节点的统计结果。

【样例输入】

3
2
3
0

【样例输出】

0 1 2

【提示】

在此键入。

【来源】

20%的数据1<=n<=1000

100%的数据1<=n<=100000

上来看了一眼题目难度是两颗黑星,感觉十分不可做(因为我一般在cogs刷两星的题目很少一遍不看题解AC)

一开始以为是树上倍增.树上DP.RMQ之类的,但是都不会啊。。

无奈只能暴力。

暴力思路:

一:读入每一个点,记录他的father,

二:枚举每一个点,如果他的father不为0且它的father的值比他大,那么它的father的值就++

正解:

DFS序+树状数组

但是看了一下评测记录我的暴力0.125s秒杀所有正解+暴力=.=

 1     #include<iostream>
 2     #include<cstdio>
 3     #include<cstring>
 4     #include<cmath>
 5     using namespace std;
 6     const int MAXN=100001;
 7     int read(int & n)
 8     {
 9         char c=‘/‘;int x=0,flag=0;
10         while(c<‘0‘||c>‘9‘)
11         {c=getchar();
12         if(c==‘-‘)flag=1;}
13         while(c>=‘0‘&&c<=‘9‘)
14         {x=x*10+c-48;c=getchar();}
15         if(flag)n=-x;
16         else n=x;
17         return n;
18     }
19     int n,p;
20     int fa[MAXN];
21     int ch[MAXN];
22     int num[MAXN];
23     int main()
24     {
25         freopen("counttree.in","r",stdin);
26         freopen("counttree.out","w",stdout);
27         read(n);
28         for(int i=1;i<=n;i++)
29         {
30             read(p);
31             fa[i]=p;
32         }
33         for(int i=1;i<=n;i++)
34         {
35             int p=i;
36             while(fa[p]!=0)
37             {
38                 if(fa[p]>i)
39                     num[fa[p]]++;
40                 p=fa[p];
41             }
42         }
43         for(int i=1;i<=n;i++)
44         {
45             printf("%d ",num[i]);
46         }
47         return 0;
48     }

1682. [HAOI2014]贴海报

★★☆   输入文件:ha14d.in   输出文件:ha14d.out   简单对比
时间限制:1 s  
内存限制:256 MB

【题目描述】

Bytetown城市要进行市长竞选,所有的选民可以畅所欲言地对竞选市长的候选人发表言论。为了统一管理,城市委员会为选民准备了一个张贴海报的electoral墙。

张贴规则如下:

1.electoral墙是一个长度为N个单位的长方形,每个单位记为一个格子;

2.所有张贴的海报的高度必须与electoral墙的高度一致的;

3.每张海报以“A B”表示,即从第A个格子到第B个格子张贴海报;

4.后贴的海报可以覆盖前面已贴的海报或部分海报。

现在请你判断,张贴完所有海报后,在electoral墙上还可以看见多少张海报。

【输入格式】

第一行:     N   M            分别表示electoral墙的长度和海报个数

接下来M行:   Ai   Bi          表示每张海报张贴的位置

【输出格式】

输出贴完所有海报后,在electoral墙上还可以看见的海报数。

【样例输入】

100 5

1 4

2 6

8 10

3 4

7 10

【样例输出】

4

【提示】

【约束条件】

1 0<= N <= 10000000     1<=M<=1000   1<= Ai <= Bi <=10000000

所有的数据都是整数。数据之间有一个空格

上来看了一眼立马用10min打出了暴力,打完T3的暴力之后回来看了一下这个题感觉是线段树的裸体

然后用15min写出了线段树

但是!!!

线段树!!

居然!!

比!!

暴力!!

慢!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

而且!!

还!!

爆内存!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

这就比较尴尬了,望着对拍程序上每次都是暴力先跑完然后线段树等一秒再出结果的场景,我还能说什么、、

难道是因为我写的线段树太丑了???

=.=

暴力思路:模拟张贴每一个海报

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 using namespace std;
 6 const int MAXN=10000001;
 7 int n,m,x,y;
 8 int read(int & n)
 9 {
10     char c=‘/‘;int x=0,flag=0;
11     while(c<‘0‘||c>‘9‘)
12     {c=getchar();
13     if(c==‘-‘)flag=1;}
14     while(c>=‘0‘&&c<=‘9‘)
15     {x=x*10+c-48;c=getchar();}
16     if(flag)n=-x;
17     else n=x;
18     return n;
19 }
20 int a[MAXN];
21 int vis[MAXN];
22 int now=1;
23 int ans=0;
24 int main()
25 {
26     freopen("a.in","r",stdin);
27     freopen("b.out","w",stdout);
28     read(n);read(m);
29     for(int i=1;i<=m;i++)
30     {
31         read(x);read(y);
32         if(x>y)swap(x,y);
33         for(int j=x;j<=y;j++)
34         a[j]=i;
35     }
36     for(int i=1;i<=n;i++)
37     {
38         if(vis[a[i]]==0&&a[i]!=0)
39         {
40             ans++;
41             vis[a[i]]=1;
42         }
43     }
44     printf("%d",ans);
45     return 0;
46 }

暴力80

正解:老师讲了个扫描线但是没听懂啊,,,,,so参考了题解的浮水法

首先我们读入每一个海报的l和r,

然后逆序扫描,默认ans为一,因为最后的一张一定能看见

对于每一个i一直向上枚举,就像浮水一样,如果经过不断的裁剪之后能够>n的话

ans++

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 const int MAXN=1001;
 8 int n,m,ans=1;
 9 int vis[MAXN];
10 struct node
11 {
12     int l;
13     int r;
14     int id;
15 }a[MAXN];
16 int read(int & n)
17 {
18     char c=‘/‘;int flag=0,x=0;
19     while(c<‘0‘||c>‘9‘)
20     {if(c==‘-‘)flag=1;
21     c=getchar();}
22     while(c>=‘0‘&&c<=‘9‘)
23     {x=x*10+(c-48);
24     c=getchar();}
25     if(flag)n=-x;
26     else n=x;
27 }
28 void water(int ll,int rr,int now,int pos)
29 {
30     if(vis[pos])
31         return ;
32     while(now<=m&&(rr<=a[now].l||ll>=a[now].r))
33     now++;
34     if(now>m)
35     {
36         vis[pos]=1;
37         ans++;
38         return ;
39     }
40     if(ll<a[now].l&&rr>a[now].l)
41         water(ll,a[now].l,now+1,pos);
42     if(rr>a[now].r&&ll<a[now].r)
43         water(a[now].r,rr,now+1,pos);
44
45 }
46 int main()
47 {
48     freopen("ha14d.in","r",stdin);
49     freopen("ha14d.out","w",stdout);
50     read(n);read(m);
51     for(int i=1;i<=m;i++)
52     {
53         read(a[i].l);
54         read(a[i].r);
55         a[i].r=a[i].r+1;
56         a[i].id=i;
57     }
58     for(int i=m-1;i>=1;i--)
59     {
60         water(a[i].l,a[i].r,i+1,i);
61     }
62     printf("%d",ans);
63     return 0;
64 }

浮水法秒AC

1619. [HEOI2012]采花

★★☆   输入文件:1flower.in   输出文件:1flower.out   简单对比
时间限制:5 s  
内存限制:128 MB

【题目描述】

萧薰儿是古国的公主,平时的一大爱好是采花。

今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花。花园足够大,容纳了n朵花,花有c种颜色(用整数1-c表示),且花是排成一排的,以便于公主采花。公主每次采花后会统计采到的花的颜色数,颜色数越多她会越高兴!同时,她有一癖好,她不允许最后自己采到的花中,某一颜色的花只有一朵。为此,公主每采一朵花,要么此前已采到此颜色的花,要么有相当正确的直觉告诉她,她必能再次采到此颜色的花。由于时间关系,公主只能走过花园连续的一段进行采花,便让女仆福涵洁安排行程。福涵洁综合各种因素拟定了m个行程,然后一一向你询问公主能采到多少朵花(她知道你是编程高手,定能快速给出答案!),最后会选择令公主最高兴的行程(为了拿到更多奖金!)。

【输入格式】

第一行四个空格隔开的整数n、c以及m。接下来一行n个空格隔开的整数,每个数在[1, c]间,第i个数表示第i朵花的颜色。接下来m行每行两个空格隔开的整数l和r(l ≤ r),表示女仆安排的行程为公主经过第l到第r朵花进行采花。

【输出格式】

共m行,每行一个整数,第i个数表示公主在女仆的第i个行程中能采到的花的颜色数。

【样例输入】

5  3 5
  1  2 2 3 1
  1  5
  1  2
  2  2
  2  3
  3  5
  

【样例输出】

2
  0 0 1 0
  【样例说明】
  询问[1, 5]:公主采颜色为1和2的花,由于颜色3的花只有一朵,公主不采;询问[1, 2]:颜色1和颜色2的花均只有一朵,公主不采;
  询问[2, 2]:颜色2的花只有一朵,公主不采;
  询问[2, 3]:由于颜色2的花有两朵,公主采颜色2的花;
  询问[3, 5]:颜色1、2、3的花各一朵,公主不采。
  

【提示】

【数据范围】

对于100%的数据,1 ≤ n ≤    10^6,c ≤ n,m ≤10^6。

【来源】

【题目来源】

耒阳大世界(衡阳八中) OJ 2743

一开始以为这题是线段树,,后来发现线段树好像没有这个功能

然后就想莫队,看了看时间发现还有一个半小时,以为这道题做不出来了,就打了个暴力去做T2

临收卷还有二十分钟左右的时候老师说T3莫队20分,(后来我用莫队AC了,,,实力打脸)

暴力思路:暴力

正解:

1.裸莫队

 1     #include<iostream>
 2     #include<cstdio>
 3     #include<cstring>
 4     #include<cmath>
 5     #include<algorithm>
 6     using namespace std;
 7     const int MAXN=1000001;
 8     int colornum[MAXN],n,color,m,a[MAXN];
 9     int base,pos[MAXN],out[MAXN];
10     struct node
11     {
12         int l,r,id;
13     }q[MAXN];
14     int ans=0;
15     int read(int & n)
16     {
17         char c=‘/‘;int flag=0,x=0;
18         while(c<‘0‘||c>‘9‘)
19         {c=getchar();}
20         while(c>=‘0‘&&c<=‘9‘)
21         {x=(x<<3)+(x<<1)+(c-48);
22         c=getchar();}
23         n=x;
24     }
25     inline void dele(int where)
26     {
27         if(colornum[a[where]]==2)
28             ans--;
29         colornum[a[where]]--;
30     }
31     inline void add(int where)
32     {
33         if(colornum[a[where]]==1)
34             ans++;
35         colornum[a[where]]++;
36     }
37     inline int comp(const node & a,const node & b)
38     {
39         if(pos[a.l]==pos[b.l])
40             return a.r<b.r;
41         else return pos[a.l]<pos[b.l];
42     }
43     inline void modui()
44     {
45         int l=1,r=0;
46         for(int i=1;i<=m;++i)
47         {
48             for(;l<q[i].l;++l)
49                 dele(l);
50             for(;l>q[i].l;--l)
51                 add(l-1);
52             for(;r<q[i].r;++r)
53                 add(r+1);
54             for(;r>q[i].r;--r)
55                 dele(r);
56             out[q[i].id]=ans;
57         }
58     }
59     int main()
60     {
61         freopen("1flower.in","r",stdin);
62         freopen("1flower.out","w",stdout);
63         read(n);read(color);read(m);
64         base=sqrt(n);
65         for(int i=1;i<=n;++i)
66             read(a[i]);
67         for(int i=1;i<=n;++i)
68             pos[i]=(i-1)/base+1;
69         for(int i=1;i<=m;++i)
70         {
71             read(q[i].l);
72             read(q[i].r);
73             q[i].id=i;
74         }
75         sort(q+1,q+m+1,comp);
76         modui();
77         for(int i=1;i<=m;++i)
78         {
79             printf("%d\n",out[i]);
80         }
81         return 0;
82     }

莫队AC

2.因为一个颜色只有出现两次的时候才会被采

那么我们可以记录这个颜色出现的位置,但这个颜色出现的次数达到两次的时候,我们把这个区间+1

维护区间可以用树状数组实现

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 const int MAXN=1000001;
 8 int a[MAXN];
 9 int lb(int x)
10 {return x&-x;}
11 int read(int & n)
12 {
13     char c=‘/‘;int flag=0,x=0;
14     while(c<‘0‘||c>‘9‘)
15     {if(c==‘-‘)flag=1;
16     c=getchar();}
17     while(c>=‘0‘&&c<=‘9‘)
18     {x=x*10+(c-48);
19     c=getchar();}
20     if(flag)n=-x;
21     else n=x;
22 }
23 int n,colornum,m;
24 struct node
25 {
26     int l,r,id;
27 }q[MAXN];
28 int first[MAXN],second[MAXN],tree[MAXN],ans[MAXN];
29 int comp(const node & a ,const node & b)
30 {return a.r<b.r;}
31 void add(int pos,int v)
32 {
33     while(pos<=n)
34     {
35         tree[pos]+=v;
36         pos=pos+lb(pos);
37     }
38
39 }
40 int query(int pos)
41 {
42     int tot=0;
43     while(pos)
44     {
45         tot=tot+tree[pos];
46         pos=pos-lb(pos);// 等差序列维护所以从尾加到头
47     }
48     return tot;
49 }
50 int main()
51 {
52     //freopen("1flower.in","r",stdin);
53     //freopen("1flower.out","w",stdout);
54     read(n);read(colornum);read(m);
55     for(int i=1;i<=n;i++)
56     {
57         read(a[i]);
58         second[i]=first[a[i]];// 如果a[i]出现过的话,那么second一定是记录的第二次的位置
59         first[a[i]]=i;
60     }
61     for(int i=1;i<=m;i++)
62     {
63         read(q[i].l);read(q[i].r);
64         q[i].id=i;
65     }
66     sort(q+1,q+m+1,comp);
67     int last=1;
68     for(int i=1;i<=n;i++)
69     {
70         if(second[i])
71         {
72             add(second[i]+1,-1);
73             add(second[second[i]]+1,1);
74         }
75         while(i==q[last].r)
76         {
77             ans[q[last].id]=query(q[last].l);
78             last++;
79         }
80     }
81     for(int i=1;i<=m;i++)
82         printf("%d\n",ans[i]);
83     return 0;
84 }

采花树状数组+神奇四路

总结:这次考的可以说比较好,毕竟rank2,而且没有任何失误

   也可以说考的非常烂,因为2.3题没有一个题打出正解,虽然T2的线段树有些尴尬,但是其他的也有用线段树AC的

   赛后我看了一下其他的人提交记录,发现二区的大神们T2没用暴力都得了76-80

   还有一位T3莫队水过80

    感觉和他们的差距越来越大了。。(毕竟每天都比他们少半天,而且他们的智商都是250+-)

   继续努力吧!

时间: 2024-10-13 15:57:55

2017.5.26暴力赛解题报告的相关文章

20161026模拟赛解题报告

20161026模拟赛解题报告 By shenben T1 按照题目说的模拟即可 但这题有一个神坑:当25个字母都已经一一对应完毕后,剩下的两个字母默认对应. T2 所有的逆序对之间都会连边,求最大独立点集. 表面上是个图论题,其实是个LIS O(nlogn)求最长上升子序列的长度即可AC T3 第一次手贱,用链表存边,这是一个稠密图啊!!应该用邻接矩阵啊. 明明可以用floyed跑,非要dfs乱搞.结果10分.玩砸了吧. 最后只改到了40分. 网上的题解(没看懂): 首先这是一个神奇的图,叫做

CSU-ACM2014年校队选拔赛指导赛解题报告

•Problem A  CSU 1065                               贪心 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 const int maxn = 1000010; 6 struct Node{ 7 int a,b; 8 bool operator < (const Node& rhs)

20161027模拟赛解题报告

20161027模拟赛解题报告 By shenben T1 数学题 模拟即可. 注意开long long T2 技巧题 图片为本题第一张图.(无奈,图传不上来) 首先第一问图中的“Y 字形”的数量,这么简单,在此不细讲. 详见代码 O(n)累加一下就好了 主要说说第二问怎么搞 预处理 每个点分别与其他那些点相连 权值为第1,2,3大(若没有2,3大,就忽略).记录一下权值与对应的点的标号.目的是方便下面的判断. 枚举入度>=3的点,即点B(有多个) 再枚举点B相连的D点(不是点A,C). Ste

10.30 NFLS-NOIP模拟赛 解题报告

总结:今天去了NOIP模拟赛,其实是几道USACO的经典的题目,第一题和最后一题都有思路,第二题是我一开始写了个spfa,写了一半中途发现应该是矩阵乘法,然后没做完,然后就没有然后了!第二题的暴力都没码QAQ 现在我来写解题报告了,有点饿了QAQ.. 第一题 题目 1: 架设电话线 [Jeffrey Wang, 2007] 最近,Farmer John的奶牛们越来越不满于牛棚里一塌糊涂的电话服务,于 是,她们要求FJ把那些老旧的电话线换成性能更好的新电话线.新的电话线架设 在已有的N(2 <=

CH Round #56 - 国庆节欢乐赛解题报告

最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树,其中一些树上结有能够产生能量的魔力水果.已知每个水果的位置(Xi,Yi)以及它能提供的能量Ci.然而,魔幻森林在某些时候会发生变化:(1) 有两行树交换了位置.(2) 有两列树交换了位置.当然,树上结有的水果也跟随着树一起移动.不过,只有当两行(列)包含的魔力水果数都大于0,或者两行(列)都没有魔

20161109模拟赛解题报告

2016-11-09试题解题报告 By shenben 本解题报告解析均为100分解题思路. T1 模拟即可. 我怕极限数据5000(n,m)*100000(k). 如果用二维数组.空间勉强撑住,时间上够呛. 因此用2个一位数组分别代表行和列. 这样每次修改是O(1)的. 查询是O(nm)(只查询一次) 总时间复杂度:O(nmk) T2 搜索 一开始想偏了. 倒着由“a”往前推.结果小样例过了,大样例差太多. 于是另辟蹊径. 观察到数据范围很小. 直接枚举答案序列不就好了. 对于每个序列再判断一

2014牡丹江网络赛解题报告

The 2014 ACM-ICPC Asia Mudanjiang Regional First Round 题目链接 A题解题报告 B题解题报告 C题解题报告 D题解题报告 E题解题报告 F题解题报告 G题(未完成) H题解题报告 I题解题报告 J题解题报告

2017.9.17校内noip模拟赛解题报告

预计分数:100+60+60=220 实际分数:100+60+40=200 除了暴力什么都不会的我..... T1 2017.9.17巧克力棒(chocolate) 巧克力棒(chocolate)Time Limit:1000ms Memory Limit:64MB题目描述LYK 找到了一根巧克力棒,但是这根巧克力棒太长了,LYK 无法一口吞进去.具体地,这根巧克力棒长为 n,它想将这根巧克力棒折成 n 段长为 1 的巧克力棒,然后慢慢享用.它打算每次将一根长为 k 的巧克力棒折成两段长为 a

2017.5.20欢(bei)乐(ju)赛解题报告

预计分数:100+20+50=first 实际分数:20+0+10=gg 水灾(sliker.cpp/c/pas) 1000MS  64MB 大雨应经下了几天雨,却还是没有停的样子.土豪CCY刚从外地赚完1e元回来,知道不久除了自己别墅,其他的地方都将会被洪水淹没. CCY所在的城市可以用一个N*M(N,M<=50)的地图表示,地图上有五种符号:“. * X D S”.其中“X”表示石头,水和人都不能从上面经过.“.”表示平原,CCY和洪水都可以经过.“*”表示洪水开始地方(可能有多个地方开始发