前言:再一次OTL


JZOJ 3508 好元素

题目

求满足a[m]+a[n]+a[p]=a[i]a[m]+a[n]+a[p]=a[i]a[m]+a[n]+a[p]=a[i]的i的个数


分析

移项后得到a[m]+a[n]=a[i]−a[p]a[m]+a[n]=a[i]-a[p]a[m]+a[n]=a[i]−a[p],所以用O(n2)O(n^2)O(n2)哈希存储,再用O(n2)O(n^2)O(n2)找到答案。


代码

#include <cstdio>
#include <cctype>
#define p 19996001(抠门的哈希函数)
int n,a[5001],hash[p],ans;
inline int in(){int ans=0,f=1; char c=getchar();while (!isdigit(c)&&c!='-') c=getchar();if (c=='-') c=getchar(),f=-f;while (isdigit(c)) ans=ans*10+c-48,c=getchar();return ans*f;
}
int locate(int x){//找哈希表的位置int pos=(x%p+p)%p,i=0; while (i<p&&hash[(pos+i)%p]!=p+1&&hash[(pos+i)%p]!=x) i++;return (pos+i)%p;
}
signed main(){freopen("good.in","r",stdin);freopen("good.out","w",stdout);n=in(); for (int i=0;i<p;i++) hash[i]=p+1;for (int i=1;i<=n;i++){a[i]=in(); bool flag=0; int x;for (int j=1;j<i&&!flag;j++) if (hash[locate(a[i]-a[j])]==a[i]-a[j]) ans++,flag=1;//查询  if (i<n) for (int j=1;j<=i;j++) hash[locate(a[i]+a[j])]=a[i]+a[j];//补充哈希表}return !printf("%d",ans);
}

JZOJ 3509 倒霉的小C

题目

求1+∑i=1ngcd(n,i)1+\sum_{i=1}^ngcd(n,i)1+∑i=1n​gcd(n,i)


分析

这个问题可以改变成1+∑d∣nd∗φ(n/d),φ(n)指1到n中与n互质的数1+\sum_{d|n}d*\varphi(n/d),\varphi(n)指1到n中与n互质的数1+∑d∣n​d∗φ(n/d),φ(n)指1到n中与n互质的数,证明不会遗漏,不会重复比较简单,算出φ\varphiφ说明了每个数只会出现一次,时间复杂度O(n的约数log⁡n的约数)O(n的约数\log n的约数)O(n的约数logn的约数)


代码

#include <cstdio>
using namespace std;
typedef long long ll;
ll ans,n;
ll phi(ll n){ll ans=n;for (ll i=2;i*i<=n;i++)if (n%i==0){ans=ans/i*(i-1);while (n%i==0) n/=i;}if (n>1) ans=ans/n*(n-1);return ans;
}
int main(){freopen("beats.in","r",stdin);freopen("beats.out","w",stdout);scanf("%lld",&n); ans=1;for (ll i=1;i*i<=n;i++)if (n%i==0){ans+=i*phi(n/i);if (i*i!=n) ans+=n/i*phi(i);}return !printf("%lld",ans);
}

JZOJ 3510 最短路径

题目

在每个点经过一次的情况下从 A 走到 B,再回到 A(A点两次) 的最短路径。并且到B的路上横坐标要从小到大走,b1b_1b1​只能在到B的路上走,b2b_2b2​只能在回A的路上走,回A时横坐标要从大到小走。


分析

题目满足无后效性,所以是动态规划,两点的直线距离比较容易,但问题是如何dp
设f[i][j]f[i][j]f[i][j]表示去B的路经过i,回A的路经过j的最短路径,显然得到(k=max(i,j)+1k=max(i,j)+1k=max(i,j)+1)
f[k][j]=min(f[k][j],f[i][j]+dis[i][k])当k未经过b2f[k][j]=min(f[k][j],f[i][j]+dis[i][k])当k未经过b2f[k][j]=min(f[k][j],f[i][j]+dis[i][k])当k未经过b2
f[i][k]=min(f[i][k],f[i][j]+dis[j][k])当k未经过b1f[i][k]=min(f[i][k],f[i][j]+dis[j][k])当k未经过b1f[i][k]=min(f[i][k],f[i][j]+dis[j][k])当k未经过b1
注意i=j和f[n][n]i=j和f[n][n]i=j和f[n][n]要特判


代码

#include <bits/stdc++.h>
#define N 1001
using namespace std;
double f[N][N],dis[N][N]; int n,b1,b2,x[N],y[N];
int in(){int ans=0; char c=getchar();while (!isdigit(c)) c=getchar();while (isdigit(c)) ans=ans*10+c-48,c=getchar();return ans;
}
int main(){freopen("path.in","r",stdin);freopen("path.out","w",stdout);n=in(); b1=in(); b2=in();for (int i=1;i<=n;i++){x[i]=in(); y[i]=in();for (int j=1;j<i;j++) dis[i][j]=dis[j][i]=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));//求距离for (int j=1;j<=n;j++) f[i][j]=2147483647;}f[1][1]=0;for (int i=1;i<=n;i++)for (int j=1;j<=n;j++){if (i==j&&i>1) continue;int k=max(i,j)+1;//下一个点if (k>n){//走到终点if (i<n) f[n][n]=min(f[n][n],f[i][j]+dis[i][n]);if (j<n) f[n][n]=min(f[n][n],f[i][j]+dis[j][n]);}else{if (k!=b2+1) f[k][j]=min(f[k][j],f[i][j]+dis[i][k]);//没有经过b2if (k!=b1+1) f[i][k]=min(f[i][k],f[i][j]+dis[j][k]);//没有经过b1}}return !printf("%.2lf",f[n][n]);
}

JZOJ 3511 游戏节目

题目

队伍A,B,C有n个游戏节目,玩第i个游戏,分别可得A[i],B[i],C[i]的分数。从n个游戏节目里面挑选至少k个节目出来(被选中的节目不分次序),使得队伍A成为赢家。队伍A能成为赢家的条件是队伍A的总得分要比队伍B的总得分要高,同时也要比队伍C的总得分要高。求有多少种不同的选取方案。


分析

这道题直接求会TLE(要开long long),所以可以用总方案-不够k个节目的方案,而由于k≤7k\leq7k≤7,所以比较容易深搜,那问题是怎样求总方案,可以双向搜索,把1n/2和n/2+1n中的所有可能存下来,离散后用树状数组维护,那具体如何排序suma−b+suma−c&gt;0sum_{a-b}+sum_{a-c}&gt;0suma−b​+suma−c​>0,移项后得到suma−b&gt;−suma−csum_{a-b}&gt;-sum_{a-c}suma−b​>−suma−c​,所以最后时间复杂度
O(217log217+∑i=06C34i)≈O(1544488+1676116)=O(3220604)≈O(3.22∗106)O(2^{17}log2^{17}+\sum_{i=0}^{6} C_{34}^i)\approx O(1544488+1676116)=O(3220604)\approx O(3.22*10^6)O(217log217+∑i=06​C34i​)≈O(1544488+1676116)=O(3220604)≈O(3.22∗106)


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
#define rep(i,a,b) for (ll i=a;i<=b;i++)
using namespace std;
typedef long long ll; ll ab,ac,j=1,ans,ans1,num1,num2,t;
struct spd{ll ab,ix; bool mark;}k3[262145];
struct rec{ll ab,ac;}k1[131073],k2[131073];
int n,k,a[35],b[35],c[35],s[262145];
ll in(){ll ans=0; char c=getchar();while (!isdigit(c)) c=getchar();while (isdigit(c)) ans=ans*10+c-48,c=getchar();return ans;
}
void dfs(ll dep,ll now){if (dep>=k) return; if (ab>0&&ac>0) ans++;rep(i,now+1,n) ab+=a[i]-b[i],ac+=a[i]-c[i],dfs(dep+1,i),ab-=a[i]-b[i],ac-=a[i]-c[i];
}
void dfs1(ll now){k1[++num1]=(rec){ab,ac}; rep(i,now+1,n>>1) ab+=a[i]-b[i],ac+=a[i]-c[i],dfs1(i),ab-=a[i]-b[i],ac-=a[i]-c[i];}
void dfs2(ll now){k2[++num2]=(rec){ab,ac}; rep(i,now+1,n) ab+=a[i]-b[i],ac+=a[i]-c[i],dfs2(i),ab-=a[i]-b[i],ac-=a[i]-c[i];}
bool cmp1(spd x,spd y){return x.ab<y.ab;} bool cmp2(rec x,rec y){return x.ac<y.ac;} bool cmp3(rec x,rec y){return x.ac>y.ac;}
void add(ll x){while (x<=t) s[x]++,x+=-x&x;} ll answer(ll x){ll ans=0; while (x) ans+=s[x],x-=-x&x; return ans;}
int main(){freopen("show.in","r",stdin);freopen("show.out","w",stdout);n=in(); k=in(); t=1;rep(i,1,n) a[i]=in(); rep(i,1,n) b[i]=in(); rep(i,1,n) c[i]=in();dfs(0,0); dfs1(0); dfs2(n>>1);//三次深搜rep(i,1,num1) k3[i]=(spd){k1[i].ab,i,0};rep(i,1,num2) k3[i+num1]=(spd){-k2[i].ab,i,1};stable_sort(k3+1,k3+1+num1+num2,cmp1);//第一次快排if (!k3[1].mark) k1[k3[1].ix].ab=1; else k2[k3[1].ix].ab=1;rep(i,2,num1+num2){//离散if (k3[i].ab!=k3[i-1].ab) t++;if (!k3[i].mark) k1[k3[i].ix].ab=t; else k2[k3[i].ix].ab=t;}stable_sort(k1+1,k1+1+num1,cmp2); stable_sort(k2+1,k2+1+num2,cmp3);//第二次快排rep(i,1,num1){while (j<=num2&&k1[i].ac+k2[j].ac>0) add(k2[j].ab),j++;//树状数组维护ans1+=answer(k1[i].ab-1);//找答案}return !printf("%lld",ans1-ans);//输出总方案-不合法的方案
}

后续

向出题人orz

2018.07.18【2018提高组】模拟C组相关推荐

  1. 2018.07.17【省赛模拟】模拟B组 比赛总结

    题目 [GDKOI2003]最大公共子串 [题目描述] 从一个给定的串中删去(不一定连续地删去)0个或0个以上的字符,剩下的字符按原来的顺序组成的串是该串的字串.例如:"", &q ...

  2. 2018.07.17【省赛模拟】模拟B组 比赛题解(总结)

    今天一看排名,what the,又垫底了,新初二第一YYT287.5,第二WYD120 T1: 最大公共子串 分类讨论+DP 题目描述 从一个给定的串中删去(不一定连续地删去)0个或0个以上的字符,剩 ...

  3. JZOJ5857 【NOIP提高组模拟A组2018.9.8】没有上司的舞会

    题目 Description "那么真的有果尔德施坦因这样一个人?"他问道. "是啊,有这样一个人,他还活着.至于在哪里,我就不知道了." "那么那个 ...

  4. 【一周头条盘点】中国软件网(2018.6.18~2018.6.22)

    每一个企业级应用的人都置顶了中国软件网 中国软件网为你带来最新鲜的行业干货 趋势洞察 ========= 思科Maciej Kranz:区块链是我们这个时代的四项颠覆性技术之一 思科战略创新集团副总裁 ...

  5. JZOJ 5281. 【NOIP提高组模拟A组8.15】钦点

    Description Input Output Sample Input 4 4 2 a a b b a a b b c c d d c c d d 1 1 3 3 2 2 3 1 1 3 2 2 ...

  6. 【二分,找规律】Day 14 提高组模拟C组 T1 小麦亩产一千八

    题目大意 给定斐波那契的第aaa项,求出第b" role="presentation">bbb项,默认第0项为1 解题思路 方法一:递推 找到规律后O(b)O(b) ...

  7. JZOJ 5814. 【NOIP提高A组模拟2018.8.14】 树

    梦游中的你来到了一棵 N 个节点的树上. 你一共做了 Q 个梦, 每个梦需要你从点 u 走到点 v 之后才能苏醒, 由于你正在梦游, 所以每到一个节点后,你会在它连出去的边中等概率地选择一条走过去, ...

  8. 2018.12.08【NOIP提高组】模拟B组总结(未完成)

    2018.12.08[NOIP提高组]模拟B组总结 diyiti 保留道路 进化序列 B diyiti Description 给定n 根直的木棍,要从中选出6 根木棍,满足:能用这6 根木棍拼出一个 ...

  9. 5814. 【NOIP提高A组模拟2018.8.14】 树(期望 + 倍增)

    5814. [NOIP提高A组模拟2018.8.14] 树 Problem 给定一棵nnn个点的树,m" role="presentation">mmm次询问,每次 ...

最新文章

  1. 【组队学习】【32期】推荐系统-新闻推荐系统实践
  2. iOS使用Workspace来管理多项目
  3. Python Flask框架常用组件介绍
  4. 【C语言】数字在排序数组中出现的次数(改动)
  5. SAP S/4HANA CDS View的访问控制实现:DCL介绍 1
  6. 如何实现数组和 List 之间的转换?
  7. 利用MyBatis Generator自动创建代码
  8. java.util.Scanner简单应用
  9. vc++学习精髓(收集,整理)
  10. 拓端tecdat|R语言精算学:使用链梯法Chain Ladder和泊松定律模拟和预测未来赔款数据
  11. CSS3 修改和去除移动端点击事件出现的背景框
  12. 计算机录像怎么操作,电脑屏幕录制怎么操作?
  13. pythonttf字体下载_python 58 字体反爬
  14. kuangbin棋盘问题
  15. Dreammail 下载与安装
  16. 在上海创业的日子之了解银行企业对公基础账户收费情况
  17. 使用espressos idlingresource获得最高的Android测试速度
  18. 简洁,简单,再简化...
  19. 2018年笔试题——老虎证券1
  20. 前端项目中常用的轮子,提升开发效率

热门文章

  1. 反证法在计算机领域,人工智能的基础研究领域——问题求解、逻辑推理与定理证明...
  2. 助力假发线上销售 帕克西3D发型虚拟试戴接入电商平台使用
  3. 微信小程序顶部透明状态标题栏搜索栏与胶囊对齐
  4. VB中Byval关键字的使用。
  5. tushare更新,get_k_data支持分时k线数据,可替代以前的get_hist_data
  6. 一种在外部中心化基础下的网络空间去中心化充盈区块链系统
  7. ne_comment 表
  8. 拓扑学 计算机领域,吴国平: 拓扑学到底有多重要? 在数学中占据多高的地位?...
  9. 这俩 AI 项目贼有意思
  10. windows64位jdk678网盘下载