POJ 2886 Who Gets the Most Candies?(线段树)
2014-01-08 11:12
477 查看
学会了反素数表。
对于任何正整数x,其约数的个数记做g(x).例如g(1)=1,g(6)=4.如果某个正整数x满足:对于任意i(0<i<x),都有g(i)<g(x),则称x为反素数.
举个例子。
12 24是反素数。约数个数为6和8
在12-24之间的所有数的约数个数只会小于等于6.因为只有完全平方数的约数是奇数个。
然后就是线段树的单点更新。
定义
对于任何正整数x,其约数的个数记做g(x).例如g(1)=1,g(6)=4.如果某个正整数x满足:对于任意i(0<i<x),都有g(i)<g(x),则称x为反素数.举个例子。
12 24是反素数。约数个数为6和8
在12-24之间的所有数的约数个数只会小于等于6.因为只有完全平方数的约数是奇数个。
然后就是线段树的单点更新。
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <set> #define lson num<<1,s,mid #define rson num<<1|1,mid+1,e #define maxn 500005 using namespace std; struct node { char name[15]; int card; } save[maxn]; int tre[maxn<<2]; int rec; const int antiprime[] = {1,2,4,6,12,24,36,48,60,120,180,240,360,720,840,1260,1680,2520,5040,7560,10080,15120,20160,25200,27720,45360,50400,55440,83160,110880,166320, 221760, 277200, 332640, 498960, 554400, 665280}; const int factorNum[] = {1, 2, 3, 4, 6, 8, 9, 10, 12, 16, 18, 20, 24, 30, 32, 36, 40, 48, 60, 64, 72, 80, 84, 90, 96, 100, 108, 120, 128, 144, 160, 168, 180, 192, 200, 216, 224}; void pushup(int num) { tre[num]=tre[num<<1]+tre[num<<1|1]; } void build(int num,int s,int e) { if(s==e) { tre[num]=1; return; } int mid=(s+e)>>1; build(lson); build(rson); pushup(num); } void update(int num,int s,int e,int val) { if(s==e) { tre[num]=0; rec=s; return; } int mid=(s+e)>>1; if(tre[num<<1]>=val)update(lson,val); else update(rson,val-tre[num<<1]); pushup(num); } int query(int num,int s,int e,int l,int r) { if(l<=s && r>=e) { return tre[num]; } int mid=(s+e)>>1; if(r<=mid)return query(lson,l,r); else if(l>mid)return query(rson,l,r); else return query(lson,l,mid)+query(rson,mid+1,r); } int main() { int n,k; while(scanf("%d%d",&n,&k)!=EOF) { memset(tre,0,sizeof(tre)); for(int i=1; i<=n; i++) scanf("%s%d",save[i].name,&save[i].card); build(1,1,n); int l,r,ans; int tag=0; while(antiprime[tag]<=n)tag++; int m=antiprime[--tag]; int tans; while(m--) { update(1,1,n,k); tans=rec; int pos=save[tans].card; if(tans>1)l=query(1,1,n,1,tans-1); else l=0; if(tans<n)r=query(1,1,n,tans+1,n); else r=0; int sum=l+r; int tmp=pos; if(sum!=0)pos=pos%sum; if(pos==0)pos=tmp<0?1:-1; if(pos<0) { if(abs(pos)<=l) k=l+pos+1; else k=l+r+(pos+l)+1; } else { if(pos<=r) k=l+pos; else k=pos-r; } } printf("%s %d\n",save[tans].name,factorNum[tag]); } return 0; }
相关文章推荐
- poj 2886 Who Gets the Most Candies?(线段树-单点更新)
- POJ 2886 Who Gets the Most Candies?(线段树)
- POJ 2886 Who Gets the Most Candies? (线段树 约瑟夫环问题变种)
- POJ 2886 Who Gets the Most Candies? [线段树-单点更新]【数据结构】
- POJ 2886 Who Gets the Most Candies? 线段树
- poj 2886 Who Gets the Most Candies?(线段树)
- POJ-2886-Who Gets the MostCandies?-(线段树)
- POJ - 2886 Who Gets the Most Candies?(线段树)
- poj 2886 Who Gets the Most Candies?(线段树)
- poj 2886 Who Gets the Most Candies?(线段树和反素数)
- POJ 2886 Who Gets the Most Candies?【线段树单点更新+反素数打表】【好题】
- POJ 2886 Who Gets the Most Candies?(线段树单点更新+反素数)
- POJ - 2886 Who Gets the Most Candies?(线段树)
- POJ 2886 Who Gets the Most Candies? 线段树单点更新
- POJ 2886 Who Gets the Most Candies? 线段树。。还有方向感
- poj 2886 Who Gets the Most Candies?(线段树单点更新+反素数)真难。。。
- [poj 2886] Who Gets the Most Candies? 线段树
- POJ 2886 Who Gets the Most Candies? 线段树
- poj 2886 Who Gets the Most Candies?(线段树单点更新模拟约瑟夫环)
- POJ 2886 Who Gets the Most Candies? 线段树。。还有方向感