SRM 599 DIV1
A
首先发现对于2操作,每种素因子可以单独考虑,然后取出步数最多的计入答案,然后分别加上对每种素因子的1操作;
第二步我犯了个错误,以为最优方案是把素因子指数按二进制操作,在1的位置执行1操作,0的位置执行2操作倍增;
然后发现是错的,执行一次1操作后,之后的2操作可以完全代替1操作,这样可以节省对其他素因子的1操作...
int getbit(int x)
{
int cur=,res=;
while (cur<x) cur+=cur,res++;
return res;
}
int BigFatInteger::minOperations(int A, int B)
{
initprm();
int ans=,p=;
for (int i= ; i<cnt ; i++) if (A%prm[i]==)
{
int t=;
while (A%prm[i]==) A/=prm[i],t+=B;
ans ++;
p = max(p,getbit(t));
}
return ans+p;
}
B
题解的思路真的很棒...
首先为了简化问题,需要猜想+证明一些性质:
1) 每条边必须是整数; (无理数+无理数=无理数...)
2) L不能是奇数; (基于性质1,因为多边形形成闭合回路,坐标的奇偶变化是偶数,x0->x0,y0->y0)
接下来发现L为偶数的时候可以构造出rectangle,于是问题化简为找到一个满足要求的triangle.
然后根据格点的离散性,对称性,可以把可能的点集缩小,最后o(n2)的暴力枚举/打表.
struct node{int x,y;};
vector<node>p;
vector<int>d;
int sqt[INF+];
bool check(int x,int y)
{
int dist = x*x+y*y;
if (dist>=INF || !sqt[dist]) return false;
d.push_back(sqt[dist]);
return true;
}
int getdist(node a,node b)
{
int tmp = (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y);
if (tmp>=INF || !sqt[tmp]) return INF;
return sqt[tmp];
}
double find(int l)
{
double res = -1e20;
for (int x= ; x<=l/ ; x++ )
for (int y= ; y<=l/ ; y++ )
if (check(x,y)) p.push_back((node){x,y});
int n = p.size();
for (int i= ; i<n ; i++ )
for (int j=i+ ; j<n ; j++ ) if(d[i]+d[j]<l)
{
int t = getdist(p[i],p[j]);
if (d[i]+d[j]+t!=l) continue;
if (p[i].y*p[j].x==p[i].x*p[j].y) continue;
int tmp = max(d[i],max(d[j],t)) - min(d[i],min(d[j],t));
if (res< || res>tmp) res=tmp;
}
return res;
}
double FindPolygons::minimumPolygon(int L)
{
if (L% || L<) return -1.0;
else
{
for (int i= ; i<= ; i++ ) sqt[i*i]=i;
double ans = find(L);
if (ans>=0.0) return ans;
else return (L%==)?:;
}
}
C
不在info中的点可以乘一个排列数,问题化简为求满足info的方案数.
如果确定了info1[i]为a,那么info2[i]只能选取以a为前缀的集合...
如果info2[i]在info1中还出现过,可以递推下去考虑...
然后就会发现这个问题涉及到一个树形结构.
把所有string造成一棵前缀树,重述问题就是:假设info1[i]位置放a,info2[i]位置只能在a的子树中.
f(x,mask) 表示当前在第i个节点,分配mask集合的方案数.
答案就是f(root,11..1).
对于每个f(x,mask)有两种决策,分配给x,不分配.
然后解决子问题g(x,son,mask2) 表示给x的son分配剩下mask的方案数.
优化:预处理所有合法状态的转移.
const int mod = (int)1e9 + ;
class SimilarNames {
public:
int count(vector <string>, vector <int>, vector <int>);
};
vector<int>valid,nxt[MASK],sub[MASK],e[maxn];
map<int,int>ha;
const int root = ;
int n,m,k,id[MASK];
int getk(vector<int>u,vector<int>v){
for (int i= ; i<m ; i++ ){
if (!ha.count(u[i])) u[i]=ha[u[i]]=ha.size()-;
if (!ha.count(v[i])) v[i]=ha[v[i]]=ha.size()-;
}
return ha.size();
}
void buildtree(vector<string>names){
sort(names.begin(),names.end());
for (int i= ; i<n ; i++ ){
int fa = root;
for (int j=i- ; j>= ; j-- )
if (names[i].substr(,names[j].size())==names[j]){
fa = j;break;
}
e[fa].push_back(i);
}
}
void pretreat(vector<int>u,vector<int>v){
memset(id,-,sizeof(id));
for (int i=,j ; i<(<<k) ; i++ ){
for ( j= ; j<m ; j++ ){
int p = <<ha[u[j]];
int q = <<ha[v[j]];
if ((i&p) && ((i&q)==)) break;
}
if (j==m) {
valid.push_back(i);
id[i] = valid.size()-;
}
}
for (int i= ; i<(int)valid.size() ; i++ )
for (int j= ; j<k ; j++ ) if(valid[i]&(<<j)){
if (id[valid[i]^(<<j)]!=-)
nxt[i].push_back(id[valid[i]^(<<j)]);
}
for (int i= ; i<(int)valid.size() ; i++ )
for (int j=valid[i] ; ; j=(j-)&valid[i]){
if (id[j]!=- && id[valid[i]-j]!=-)
sub[i].push_back(id[j]);
if (!j) break;
}
}
int f[maxn][MASK],g[maxn][MASK];
int add(int &x,int y){
x += y;
while (x>=mod) x-=mod;
return x;
}
int getg(int cur,int s,int mask){
if (s>=) return g[e[cur][s]][mask];
else return !valid[mask];
}
void dfs(int cur){
int s = e[cur].size();
for (int i= ; i<s ; i++ )
dfs(e[cur][i]); for (int i= ; i<s ; i++ ){
for (int j= ; j<(int)valid.size() ; j++ ){
for (int x= ; x<(int)sub[j].size() ; x++ ){
int A = valid[j];
int B = valid[sub[j][x]];
int p = getg(cur,i-,id[B]);
int q = f[e[cur][i]][id[A-B]];
g[e[cur][i]][j] = add(g[e[cur][i]][j],((llong)p*q)%mod);
}
}
} for (int i= ; i<(int)valid.size() ; i++ ){
f[cur][i] = add(f[cur][i],getg(cur,s-,i));
if (cur!=root){
for (int j= ; j<(int)nxt[i].size() ; j++ )
f[cur][i] = add(f[cur][i],getg(cur,s-,nxt[i][j]));
}
}
}
int SimilarNames::count(vector <string> names, vector <int> u, vector <int> v){
n = names.size();
m = u.size();
k = getk(u,v);
buildtree(names);
pretreat(u,v);
dfs(root);
llong ans = f[root][id[(<<k)-]];
for (int i=n-k ; i> ; i-- ) ans = (llong)(ans*i)%mod;
return (int)ans;
}
SRM 599 DIV1的更多相关文章
- Topcoder口胡记 SRM 562 Div 1 ~ SRM 599 Div 1
据说做TC题有助于提高知识水平? :) 传送门:https://284914869.github.io/AEoj/index.html 转载请注明链接:http://www.cnblogs.com/B ...
- Topcoder SRM 643 Div1 250<peter_pan>
Topcoder SRM 643 Div1 250 Problem 给一个整数N,再给一个vector<long long>v; N可以表示成若干个素数的乘积,N=p0*p1*p2*... ...
- Topcoder Srm 726 Div1 Hard
Topcoder Srm 726 Div1 Hard 解题思路: 问题可以看做一个二分图,左边一个点向右边一段区间连边,匹配了左边一个点就能获得对应的权值,最大化所得到的权值的和. 然后可以证明一个结 ...
- 图论 SRM 674 Div1 VampireTree 250
Problem Statement You are a genealogist specializing in family trees of vampires. Vampire famil ...
- SRM 583 DIV1
A 裸最短路. class TravelOnMars { public: int minTimes(vector <int>, int, int); }; vector<int> ...
- SRM 590 DIV1
转载请注明出处,谢谢viewmode=contents">http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlov ...
- Topcoder SRM 602 div1题解
打卡- Easy(250pts): 题目大意:rating2200及以上和2200以下的颜色是不一样的(我就是属于那个颜色比较菜的),有个人初始rating为X,然后每一场比赛他的rating如果增加 ...
- 状态压缩DP SRM 667 Div1 OrderOfOperations 250
Problem Statement Cat Noku has just finished writing his first computer program. Noku's compute ...
- 数学 SRM 690 Div1 WolfCardGame 300
Problem Statement Wolf Sothe and Cat Snuke are playing a card game. The game is played with exa ...
随机推荐
- 查询死锁和处理死锁(SqlServer)
-------------------查询死锁,极其引起的原因-------------------------------use master go create procedure sp_who_ ...
- JS(四)
JS的属性好多,方法好多,一下子塞进来真的需要时间消化,很多东西都是当时记得很清楚,但忘得很快,看来需要经常去复习,主要是感觉后面一点的练习题好像少了点,所以就显得不是很熟练. 1.About Tim ...
- tomcat端口占用后的解决办法
学 习网页设计的同学都会用到tomcat这个软件,在安装的时候我们一般都会选择端口为8080端口,这个端口一般情况下是不会有程序占用的,所以我们运行 tomcat不会出现什么问题,但是如果一旦别占用, ...
- lesson1:压测普通网页
本文展示了利用jmeter来压力测试普通网页,具体步骤如下: 1.添加[线程组]“lesson1压测普通网页”,“线程数”设置为10:“循环测试“设置为50,如图所示: 2.添加一个"htt ...
- repo简介
高通的Android JellyBean库已经建立完成,目前已经可以正常访问,可以正常提交.Repo获取代码注意:1. 首先应有一个repo脚本,并将脚本放到环境变量里,此脚本的配置方法a) 进入用户 ...
- Use GraceNote SDK in iOS(一)通过序列化GDO查询专辑封面
于Use MusicBrainz in iOS之后,因为MusicBrainz找出专辑封面,它只能转移到其他网站提供的音乐信息搜索服务,领导给出GraceNote.(有压力.. .) 需求类似:通过一 ...
- C#位移运算符
代码如下: /// <summary> /// 位移运算符"<<"左位移运算符,">>"右位移运算符 /// 在进行位移运算 ...
- TreeGrid( 树形表格)
本节课重点了解 EasyUI 中 TreeGrid(树形表格)组件的使用方法,这个组件依赖于DataGrid(数据表格)组件 一. 加载方式//建立一个 JSON 文件[{"id" ...
- POj3421 X-factor Chains(质因数分解+排列组合)
POj3421X-factor Chains 一开始没读懂题意,不太明白 Xi | Xi+1 where a | b means a perfectly divides into b的意思,后来才发现 ...
- Java并发编程与技术内幕:线程池深入理解
摘要: 本文主要讲了Java当中的线程池的使用方法.注意事项及其实现源码实现原理,并辅以实例加以说明,对加深Java线程池的理解有很大的帮助. 首先,讲讲什么是线程池?照笔者的简单理解,其实就是一组线 ...