想把最近几年的NOIP T4都先干掉,就大概差16年的,所以来做一做。

然后这题就浪费了我一整天QAQ...果然还是自己太弱了QAQ

点我看题

还是pa洛谷的...

题意:给m个物品,每个物品有一个不超过n的数xi。

如果存在四元组 (a,b,c,d)满足

①        xa<xb<xc<xd

  ②   xb-xa=2(xd-xc)

③       xb-xa<(xc-xb)/3

辣么这个四元组是有效的,问每个物品分别作为有效四元组中 a,b,c,d 几次

思路:16年是第一次参加的noip啊...结果炸的挺惨的,比赛的时候这题没多少时间打了,就草草打了一个暴力优化,结果细节没考虑挂掉了。

今天再来写的时候先敲了暴力,一个简单的暴力优化可以水到85分,所以真的是暴力出奇迹啊=v=

辣正解捏,不得不说这题的数学成分实在太高,我想了整整一个下午都没搞懂,但其实真的不是很难吧...

我们可以这样去想,把每一个物品的数字都抽象为一个数轴上的点的坐标。

然后画图。

可以这样考虑,设xd-xc=i 则 xb-xa=2*(xd-xc)=2*i

把化简的二式带入三式 得:  6*i<xc-xb  设6*i+k=xc-xb   ( 就是把差的部分补上去,这个姿势貌似还挺有用)

这样的话就可以画图了,由一式条件和化简后的式子可以得到这样的图

图丑就别喷了...  所以 AD=9i+k 所以 i 的取值范围也可以得到 1≤i≤n/9 (准确来说 i 要比n更小,不过没什么影响)

画完图是不是清晰了一点(其实并没有啊)

然后我萌就可以这样想了,如果知道了 i  和 A 就可以得到 B    如果知道  i  和 C 就可以得到 D  但是如果仅知道某两项是得不到其他的。

我萌把A和B看成一个整体,把C和D看成一个整体,并分别求答案。

我萌枚举 i ,然后枚举 A  这样可以算出 B, 同时 我萌可以知道 C 和 D的最小位置 即当 k=1 时 C=A+8i+1,D=A+9i+1, 知道这个最小位置有什么用?

因为知道A的答案=数字为B的物品个数*数字为C的物品个数*数字为D的物品个数

而对于任意k,如果存在数字C的位置有物品且D的位置有物品,辣么很显然 数字为C的物品个数*数字为D的物品个数 可以通过枚举A的过程中利用后缀和进行累积,然后又因为要后缀和,所以A就得从后往前枚举。

B的答案类似,在A进行求答的时候可以一起求了。

B的答案=数字为A的物品个数*数字为C的物品个数*数字为D的物品个数

辣CD为一个整体的时候捏,类比啊,一样的,但是发现数字为A的物品个数*数字为B的物品个数 累积的时候是前缀和了,所以C的枚举就是从前往后。

一道很棒的题,很棒的数学题...(困惑了我好久,看题解还看不懂!!)

  1. var n,m:longint;
  2. a,id,num:array[..]of longint;
  3. l:array[..]of longint;
  4. i,j,k,d:longint;
  5. z:longint;
  6. numab,numcd:longint;
  7. sum:array[..,..]of longint;
  8. begin
  9. read(n,m);
  10. for i:= to m do
  11. begin
  12. read(a[i]);
  13. inc(num[a[i]])
  14. end;
  15. for i:= to (n div ) do
  16. begin
  17. numcd:=;
  18. for j:=n-(*i+) downto do
  19. begin
  20. numcd:=numcd+num[j+*i+]*num[j+*i+];
  21. inc(sum[j,],num[j+*i]*numcd);
  22. inc(sum[j+*i,],num[j]*numcd);
  23. end;
  24. numab:=;
  25. for j:=*i+ to n-i do
  26. begin
  27. numab:=numab+num[j-*i-]*num[j-*i-];
  28. inc(sum[j,],num[j+i]*numab);
  29. inc(sum[j+i,],num[j]*numab);
  30. end;
  31. end;
  32. for i:= to m do
  33. begin
  34. for j:= to do
  35. write(sum[a[i],j],' ');
  36. writeln;
  37. end;
  38. end.

NOIP2016 T4

转c++后重新写了一遍这题,有了更好的理解代码一起pia上来

  1. #include<cstdio>
  2. #define ll long long
  3. using namespace std;
  4. ll ans[][];
  5. int a[],num[];
  6. int main(){
  7. int n,m;
  8. scanf("%d%d",&n,&m);
  9. for (int i=;i<=m;i++){
  10. scanf("%d",&a[i]);
  11. num[a[i]]++;
  12. }
  13. for (int t=;t<=n/;t++){
  14. ll sum=;
  15. for (int i=*t+;i<=n-t;i++){
  16. sum+=1ll*num[i-*t-]*num[i-*t-];
  17. ans[i][]+=sum*num[i]*num[i+t];
  18. ans[i+t][]+=sum*num[i]*num[i+t];
  19. }
  20. sum=;
  21. for (int i=n-*t-;i>*t;i--){
  22. sum+=1ll*num[i+*t+]*num[i+*t+];
  23. ans[i][]+=sum*num[i]*num[i-*t];
  24. ans[i-*t][]+=sum*num[i]*num[i-*t];
  25. }
  26. }
  27. for (int i=;i<=m;i++){
  28. for (int j=;j<=;j++)
  29. printf("%lld ",ans[a[i]][j]/num[a[i]]);
  30. printf("\n");
  31. }
  32. return ;
  33. }
  34. /*
  35. 条件① Xa<Xb<Xc<Xd
  36. ② Xb-Xa=2(Xd-Xc)
  37. ③ Xb-Xa<(Xc-Xb)/3
  38. 可以发现Xd-Xc是一个最小单位
  39. 设 t=Xd-Xc;
  40. ②得Xb-Xa=2t
  41. ③得2t<(Xc-Xb)/3 即6t<Xc-Xb
  42. 粗略的画图
  43. --------------------
  44. A B------C D
  45. --- >6t ----
  46. t 2t
  47. D最大是n A最小是1
  48. 所以t的取值就是
  49. 1<=t<=(n-1)/t
  50. 粗略的
  51. 1<=t<=n/t 因为数组开大后溢出没有任何影响
  52. 于是枚举t 再枚举C
  53. D的位置就得到了
  54. 而因为BC之间只要大于6t就行。
  55. 所以设C1<C2 D1<D2
  56. C1 D1所能匹配的A B C2 D2 也可以
  57. 于是满足了前缀和
  58. 只要往后枚举C的时候把上一个C的A B组数保存着累加就好了
  59. A B同理,枚举 B,A确定 C D变成了后缀和。
  60. 画图把B C的取值范围算一下即可
  61. */

NOIP2016 T4

果然自己真的要多做题啊QAQ

NOIP2016 T4 魔法阵 暴力枚举+前缀和后缀和优化的更多相关文章

  1. CodeForces 742B Arpa’s obvious problem and Mehrdad’s terrible solution (暴力枚举)

    题意:求定 n 个数,求有多少对数满足,ai^bi = x. 析:暴力枚举就行,n的复杂度. 代码如下: #pragma comment(linker, "/STACK:1024000000 ...

  2. 2014牡丹江网络赛ZOJPretty Poem(暴力枚举)

    /* 将给定的一个字符串分解成ABABA 或者 ABABCAB的形式! 思路:暴力枚举A, B, C串! */ 1 #include<iostream> #include<cstri ...

  3. HNU 12886 Cracking the Safe(暴力枚举)

    题目链接:http://acm.hnu.cn/online/?action=problem&type=show&id=12886&courseid=274 解题报告:输入4个数 ...

  4. 51nod 1116 K进制下的大数 (暴力枚举)

    题目链接 题意:中文题. 题解:暴力枚举. #include <iostream> #include <cstring> using namespace std; ; ; ch ...

  5. (算是dp吧) 小茗的魔法阵 (fzu 2225)

    http://acm.fzu.edu.cn/problem.php?pid=2225   Problem Description 在打败了易基•普罗布朗.诺姆•普罗布朗之后,小茗同学开始挑战哈德•普罗 ...

  6. Codeforces Round #349 (Div. 1) B. World Tour 最短路+暴力枚举

    题目链接: http://www.codeforces.com/contest/666/problem/B 题意: 给你n个城市,m条单向边,求通过最短路径访问四个不同的点能获得的最大距离,答案输出一 ...

  7. bzoj 1028 暴力枚举判断

    昨天梦到这道题了,所以一定要A掉(其实梦到了3道,有两道记不清了) 暴力枚举等的是哪张牌,将是哪张牌,然后贪心的判断就行了. 对于一个状态判断是否为胡牌,1-n扫一遍,然后对于每个牌,先mod 3, ...

  8. POJ-3187 Backward Digit Sums (暴力枚举)

    http://poj.org/problem?id=3187 给定一个个数n和sum,让你求原始序列,如果有多个输出字典序最小的. 暴力枚举题,枚举生成的每一个全排列,符合即退出. dfs版: #in ...

  9. hihoCoder #1179 : 永恒游戏 (暴力枚举)

    题意: 给出一个有n个点的无向图,每个点上有石头数个,现在的游戏规则是,设置某个点A的度数为d,如果A点的石子数大于等于d,则可以从A点给每个邻接点发一个石子.如果游戏可以玩10万次以上,输出INF, ...

随机推荐

  1. jQuery的一些小技巧()

    1.判断某元素上是否绑定了某种类型的事件 var $events = $("#foo").data("events"); if( $events &&a ...

  2. JZOJ.5328【NOIP2017模拟8.22】世界线

    Description

  3. 在android真机上使用sqlite3

    #zijun#2013.10.29#QQ:223663737 在android真机上使用sqlite3 前期准备: 1:保证手机已经ROOT 操作步骤: 1 : 打开CMD 2 : 进入android ...

  4. 条件注释判断IE浏览器版本

    lt,lte,gt,gte分别表示什么 lt:小于当前版本 lte:小于或等于当前版本,包括本身 gt:大于当前版本 gte:大于或等于当前版本,包括本身 使用格式 // 如IE9以下(不包括IE9加 ...

  5. [ASP.NET 大牛之路]03 - C#高级知识点概要(2) - 线程和并发

    目录: 1.线程简单使用 2.并发和异步的区别 3.并发控制—锁 4.线程的通信机制 5.线程池中的线程 6.案例:支持并发的异步日志组件 7.结束 1.线程的简单使用---------------- ...

  6. C#实现像Git那样计算Hash值

    从Git Tip of the Week: Objects一文中得知,Git是这样计算提交内容的Hash值的: Hash算法用的是SHA1 计算前,会在内容前面添加"blob 内容长度\0& ...

  7. c# 公共方法

    MyMeans using System; using System.Collections.Generic; using System.Text; using System.Windows.Form ...

  8. nginx ---refine---按需时间/流量进行调整后台服务器---geocity,proxypass

    原理相当于配置文件在启动时进行编译,proxyPass http://mydomain/path/xxxx这种方式是编译成静态的,直接替换成它解析到的ip/vip,只有重新启动时才会重新解析. 而 s ...

  9. ArcEngine几何变换中的策略模式

    使用策略模式可以减少分支语句,switch...Case,同时便于策略的扩展. 1. ITransform2D接口的Transform方法: [C#]public void Transform ( e ...

  10. HDFS中的读写数据流

    1.文件的读取 在客户端执行读取操作时,客户端和HDFS交互过程以及NameNode和各DataNode之间的数据流是怎样的?下面将围绕图1进行具体讲解. 图 1 客户端从HDFS中读取数据 1)客户 ...