Problem A,B,C:

简单的模拟,注意A中p mod q时对q=0特殊处理(注意范围)


Problem D:

Brief Intro:

给定长度为N的数组A,将A中所有连续子序列分成最少的组,使得每组任意一对数的积均为完全平方数

求最终分成组数为K的子序列个数,K属于[1,N]

Algorithm:

能推出的性质:若P,Q两数积为完全平方数,则任意一个质因子的次幂的奇偶性必然相同

那么想判断P,Q是否满足条件,只要保留每个质因子的次幂为0或1,再判断P,Q是否相同即可

下面只要考虑如何O(N^2)地判断

为了能O(1)判断新加入的数是否已经出现过,需要预处理出每一个数的上一个“自己”出现的位置

由于数的范围过广,使用map记录一个数在检索到k时最后的位置

Code:

#include <bits/stdc++.h>

using namespace std;

const int MAXN=+;
int n,dat[MAXN],res[MAXN],pre[MAXN]; vector<int> prime;
map<int,int> mp; bool isprime(int x)
{
int up_limit=sqrt(x);
for(int i=;i<=up_limit;i++)
if(x%i==) return false;
return true;
} void init()
{
int up_limit=sqrt(1e8+);
for(int i=;i<=up_limit;i++)
if(isprime(i)) prime.push_back(i);
} int trans(int x)
{
int up_limit=sqrt(abs(x)),ret=x;
for(int i=;i<prime.size();i++)
{
if(prime[i]>up_limit || ret== || ret==-) break; int t=ret,cnt=;
while(t%prime[i]==) t/=prime[i],cnt++;
if(cnt%==) ret=t*prime[i];
else ret=t;
}
return ret;
} int main()
{
cin >> n;
for(int i=;i<=n;i++)
cin >> dat[i]; init(); for(int i=;i<=n;i++) //质因数分解
dat[i]=trans(dat[i]); for(int i=;i<=n;i++) //预处理pre
if(mp.count(dat[i]))
{
pre[i]=mp[dat[i]];
mp[dat[i]]=i;
}
else
{
pre[i]=-;
mp[dat[i]]=i;
} for(int i=;i<=n;i++)
{
bool f=true;int cnt=;
for(int j=i;j<=n;j++)
{
if(dat[j]) f=false;
if(pre[j]<i && dat[j]) cnt++,mp[dat[j]]=true; //O(1)判断
if(!f) res[cnt]++;
else res[]++;
}
} for(int i=;i<=n;i++) cout << res[i] << " ";
return ;
}

Review:

1、特解:0

在看到数据范围后,总要考虑特解。

除非一段全部为0,否则忽略当前遇到的0

2、积为完全平方数的性质:

我当时只想到了传导性,反而忽略了每个质因子次幂奇偶性相同这一性质

只考虑奇偶性   到    转化后判断相等的方法值得借鉴

3、求解一串数中不同数的个数的预处理:

求出每一个数前一次出现的位置     常用的预处理方式

Problem E:

一棵树中有N个点,每个点的权值为2^N

要舍去K个点,使得这K个点的权值和最小,且剩下的点连通

Algorithm:

显而易见的贪心策略:

反向求解,寻找n-k个要选的点

由于第n个点的权值 > 1~n-1的权值和,所以从第n个点开始贪心选取即可

为了将复杂度控制在 O(NlogN) ,使用树上倍增查找路径终点

Code:

#include <bits/stdc++.h>

using namespace std;

const int MAXN=1e6+;
vector<int> G[MAXN],res;
int n,k,f[MAXN][],vis[MAXN],dep[MAXN]; inline int read()
{
char ch;int f=,num;
while(!isdigit(ch=getchar())) f|=(ch=='-');
num=ch-'';
while(isdigit(ch=getchar())) num=num*+ch-'';
return f?-num:num;
} void dfs(int cur,int anc) //初始化
{
dep[cur]=dep[anc]+;f[cur][]=anc;
for(int i=;i<=;i++) f[cur][i]=f[f[cur][i-]][i-]; for(int i=;i<G[cur].size();i++)
{
int v=G[cur][i];
if(v==anc) continue;
dfs(v,cur);
}
} int main()
{
n=read();k=read();
for(int i=;i<n;i++)
{
int x=read(),y=read();
G[x].push_back(y);G[y].push_back(x);
} dfs(n,); memset(vis,,sizeof(vis));
vis[n]=vis[]=;k=n-k-;
for(int i=n-;i>=;i--)
{
if(vis[i]) continue; int t=i;
for(int j=;j>=;j--) //倍增找路径
if(!vis[f[t][j]]) t=f[t][j]; if(dep[i]-dep[t]+<=k)
{
k-=(dep[i]-dep[t]+);
t=i;
while(!vis[t]) vis[t]=,t=f[t][];
}
else res.push_back(i);
} sort(res.begin(),res.end());
for(int i=;i<res.size();i++) cout << res[i] << " ";
return ;
}

Review:

1、当正向贪心难以实现时,可以尝试反向贪心

2、当要在树上O(logN)搜寻路径时,使用树上倍增法

Codeforces #480 Tutorial的更多相关文章

  1. [Codeforces #172] Tutorial

    Link: Codeforces #172 传送门 A: 一眼看上去分两类就可以了 1.每个矩形只有两条边相交,重合的形状为菱形 2.每个矩形四条边都有相交 对于情况1答案为$h*h/sin(a)$ ...

  2. [Codeforces #514] Tutorial

    Link: Codeforces #514 传送门 很简单的一场比赛打崩了也是菜得令人无话可说…… D: 一眼二分,发现对于固定的半径和点,能包含该点的圆的圆心一定在一个区间内,求出区间判断即可 此题 ...

  3. [Codeforces #210] Tutorial

    Link: Codeforces #210 传送门 A: 贪心,对每个值都取最大值,不会有其他解使答案变优 #include <bits/stdc++.h> using namespace ...

  4. [Codeforces #196] Tutorial

    Link: Codeforces #196 传送门 A: 枚举 #include <bits/stdc++.h> using namespace std; #define X first ...

  5. [Codeforces #174] Tutorial

    Link: Codeforces #174 传送门 A: 求原根的个数,有一条性质是原根个数为$\phi(\phi(n))$,多了一个不会证的性质 如果要确定哪些是原根的话还是要枚举,不过对于每个数不 ...

  6. [Codeforces #190] Tutorial

    Link: Codeforces #190 传送门 A: 明显答案为$n+m-1$且能构造出来 #include <bits/stdc++.h> using namespace std; ...

  7. [Codeforces #211] Tutorial

    Link: Codeforces #211 传送门 一套非常简单的题目,但很多细节都是错了一次才能发现啊…… 还是不能养成OJ依赖症,交之前先多想想corner case!!! A: 模拟,要特判0啊 ...

  8. [Codeforces #192] Tutorial

    Link: Codeforces #192 传送门 前两天由于食物中毒现在还要每天挂一天的水 只好晚上回来随便找套题做做找找感觉了o(╯□╰)o A: 看到直接大力模拟了 但有一个更简便的方法,复杂度 ...

  9. #2 codeforces 480 Parcels

    题意: 就是有一个用来堆放货物的板,承重力为S.现在有N件货物,每件货物有到达的时间,运走的时间,以及重量,承重,存放盈利.如果这件货物能再运达时间存放,并在指定时间取走的话,就能获得相应的盈利值.货 ...

随机推荐

  1. js和jquery修改背景颜色的区别

    html: <HTML> <head> <meta http-equiv="content-type" content="text/html ...

  2. 精通JS正则表达式(转)

    精通JS正则表达式,讲的比较详细,学习正则表达式的朋友可以参考下.    正则表达式可以: •测试字符串的某个模式.例如,可以对一个输入字符串进行测试,看在该字符串是否存在一个电话号码模式或一个信用卡 ...

  3. 转:RBAC权限控制

    名词解释: RBAC:Role-Based Access Control,基于角色的访问控制   关键词: RBAC,Java Shiro,Spring Security,   一. RBAC 要解决 ...

  4. iBatis之Iterator的使用

    一:前言 现在这个项目使用的是iBatis,我刚刚开始的时候说是用MyBatis,因为我以前用过,觉得还是比较好用的啊,而且不像iBatis样,查什么一个字段不能多也不能少,觉得好无语啊. 二:内容 ...

  5. 汕头市队赛 SRM 07 B 好玩的麻将

    B 好玩的麻将 SRM 07 背景&&描述 天才麻将少女KPM立志要在日麻界闯出一番名堂.     KPM上周又打了n场麻将,又控了分使得自己的排名是1..n的一个排列.     但她 ...

  6. 【洛谷 P4342】[IOI1998]Polygon(DP)

    题目链接 题意不再赘述. 这题和合并石子很类似,但是多了个乘法,而乘法是不满足"大大得大"的,因为两个非常小的负数乘起来也会很大,一个负数乘一个很大的整数会很小,所以我们需要添加一 ...

  7. autoKeras Windows 的入门测试

    在测试中分析一下ide的效果,在pycharm中测试的时候老师提示内存溢出,而且跑autoKeras的cnn时确实消耗很大空间.但是同样的电脑,换了vscode进行测试的时候没有问题.我也不知道什么回 ...

  8. Centos安装流量监控工具iftop笔记

    Centos安装流量监控工具iftop笔记 一.概述 iftop可以用来监控网卡的实时流量(可以指定网段).反向解析IP.显示端口信息等,详细的将会在后面的使用参数中说明.官方网站:http://ww ...

  9. python接口自动化12-案例分析(csrfToken)【转载】

    前言: 有些网站的登录方式跟前面讲的博客园和token登录会不一样,把csrfToken放到cookie里,登录前后cookie是没有任何变化的,这种情况下如何绕过前端的验证码登录呢? 一.登录前后对 ...

  10. Vim常见配置与命令

    本文引自http://www.acczy.net/?p=301,在自己这里放一个以后方便查看 1. 基本安装 安装Vim,Windows系统中的主目录(类似于Linux的Home)中建立vimfile ...