noip2016十连测 Round #3

A:平均数

题目描述:有一天,小A得到了一个长度为n的序列。他把这个序列的所有连续子序列都列了出来,并对每一个子序列都求了其
平均值,然后他把这些平均值写在纸上,并对它们进行排序,最后他报出了第k小的平均值。你要做的就是模仿他
的过程。

思路:二分答案,然后判断二分的结果是不是恰好为第k位。首先统计出每一个元素和平均值的差值,记为d[i],对于区间[l,r],

如果d[l]~d[r]之和要大于0,那么这段区间的平均值就一定要大于二分的答案。于是考虑求出前缀和,记为sumd[i],那么

区间[l,r]的答案就是sumd[r]-sumd[l-1],即有多少对sumd[r]-sumd[l-1]<0即为答案。喜闻乐见的求逆序对个数,

树状数组或归并排序即可,加上二分时间复杂度就是O(nlog^2n)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 #define min(x,y) ((x)>(y)?(y):(x))
 8 #define max(x,y) ((x)>(y)?(x):(y))
 9 #define maxn 100010
10 #define eps 1e-6
11
12 int n,k;
13 double l,r,ans;
14 int a[maxn],c[maxn];
15
16 struct node{
17     double sumave;
18     int size;
19 }d[maxn];
20 bool operator <(node a,node b){return a.sumave>b.sumave||(a.sumave==b.sumave&&a.size<b.size);}
21
22 int read(){
23     int x=0,f=1;char ch=getchar();
24     for (;ch<‘0‘||ch>‘9‘;ch=getchar()) if (ch==‘-‘) f=-1;
25     for (;ch>=‘0‘&&ch<=‘9‘;ch=getchar()) x=x*10+ch-‘0‘;
26     return x*f;
27 }
28
29 void change(int x){
30     while (x<=n){c[x]++;x+=x&(-x);}
31 }
32
33 int query(int x){
34     int ans=0;
35     while (x){ans+=c[x];x-=x&(-x);}
36     return ans;
37 }
38
39 bool check(double x){
40     int ck=0;
41     for (int i=1;i<=n;i++){d[i].sumave=d[i-1].sumave+a[i]-x,d[i].size=i;if (d[i].sumave<0) ck++;}
42     sort(d+1,d+n+1);memset(c,0,sizeof(c));
43     for (int i=1;i<=n;i++) ck+=query(d[i].size),change(d[i].size);
44     return ck>=k;
45 }
46
47 int main(){
48     n=read(),k=read();
49     for (int i=1;i<=n;i++) a[i]=read();
50     l=-1e9,r=1e9;
51     while (l+eps<r){
52         double mid=(l+r)/2;
53         if (check(mid)) r=mid,ans=mid;
54         else l=mid;
55     }
56     printf("%.4lf\n",ans);
57     return 0;
58 }

A

B:涂色游戏

题目描述:小A和小B在做游戏。他们找到了一个n行m列呈网格状的画板。小A拿出了p支不同颜色的画笔,开始在上面涂色。看
到小A涂好的画板,小B觉得颜色太单调了,于是把画板擦干净,希望涂上使它看起来不单调的颜色(当然,每个格
子里只能涂一种颜色)。小B想知道一共有多少种不单调的涂色方案。我们定义一个涂色方案是不单调的,当且仅
当任意相邻两列都出现了至少q种颜色。

思路:

时间: 2024-08-06 16:04:45

noip2016十连测 Round #3的相关文章

noip2016十连测题解

以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #include <string.h> #include <time.h> #include <stdlib.h> #include <string> #include <bitset> #include <vector> #include <

noip2016十连测round2

A: Divisors 题意:给定 m 个不同的正整数 a 1 ,a 2 ,...,a m ,请对 0 到 m 每一个 k 计算,在区间 [1,n] 里有多少正整数 是 a 中恰好 k 个数的约数. n,ai<=10^9,m<=200 做法:每个数的约数个数为sqrt(n)级别的,所以一共有msqrt(ai)个,对于计算答案,用哈希表判重计算即可. B:Market 题意:在比特镇一共有 n 家商店,编号依次为 1 到 n.每家商店只会卖一种物品,其中第 i 家商店的物品 单价为 c i ,价

NOIp2016 十连测 round1

Claris大爷出的一套模拟题.问别人要到了一份题,加深了自己NOIp要滚粗的感觉. Matser zzDP题,我只能说我第一遍写的时候还写崩了QAQ. //master //by Cydiater //2016.10.21 #include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <string> #include <algor

Noi2016十连测第二场-黑暗 (二项式定理/斯特林数+CDQ+NTT)

Noi2016十连测第二场-黑暗 (二项式定理/斯特林数+CDQ+NTT) 题意: n 个点的无向图,每条边都可能存在,一个图的权值是连通块个数的 m 次方,求所有可能的图的权值和. 考虑\(dp[i][j]\)表示\(j\)个点,权值为\(i\)次方 我们首先要预处理出\(n\)个点无向联通图的数量\(g[i]\),模板题:BZOJ-3456 题解 对于\(dp[i][j]\),枚举\(1\)号点所在的连通块大小为\(x\),那么可以得到的是\(dp[i][j]=\sum dp[k][j-x]

暑假第十二测

题解:第一题: 打表找规律,从12以后每次加49,我一直在前十找规律,,找了半天,以后还是多打点,学聪明点 #include <bits/stdc++.h> #define ll long long using namespace std; int zl[4] = {1,5,10,50}; ll ans[] = {0,4,10,20,35,56,83,116,155,198,244,292,341,390,439,488,537,586,635,684,733,782,831,880,929,

NOI十连测 第五测 T1

1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<iostream> 5 #include<algorithm> 6 int f[257][257],n,type,V[257],g[257][257],ans,cnt; 7 char op[204]; 8 int read(){ 9 int t=0,f=1;char ch=getchar(); 10 while

[Noi2016十连测第三场]线段树

1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 using namespace std; 7 #define maxn 100005 8 #define maxk 4000005 9 int n,m,q,tot,t1,t2,ans,L[maxn][18],R[maxn][18]; 1

[NOI十连测] 二进制的世界

题意 给定一个长度为 n 的序列 A , 以及一种位运算 Op . 对于每个位置 x , 求 $\min_{y < x} A[y] ~ Op ~ A[x]$ . n <= 100000, 0 <= A[i] <= 65536 . 一个高效的Trick 我们可以贪心地尽可能使高的位大. g[x] 表示前 8 位为 x 的一个 vector . 我们维护 g 进行剪枝. 1 #include <cstdio> 2 #include <cstring> 3 #in

[BZOJ]2017省队十连测推广赛1

听学长说有比赛就随便打一打. A.普通计算姬 题目大意:给出一棵带权树,支持一下两种操作:1.修改一个点的权值:2.给出l,r,询问以点l为根的子树和.点l+1为根的子树和.点l+2为根的子树和--点r为根的子树和的总和.(点数.操作数不超过10^5) 思路:感觉是三题中最难的.给出的[l,r]区间在树上没有实际意义,不好利用数据结构维护.考虑若不修改,可以一遍dfs算出每个点对应的dfs序,这样每棵子树都对应一个dfs序的区间,前缀和一下就能O(1)查子树和,再按点的编号顺序把子树和前缀和一下