Dairy of CDQZ 3&4

来源:互联网 发布:揭秘朝阳群众 知乎 编辑:程序博客网 时间:2024/04/29 22:18

不知不觉周末了,发现自己没有干什么事,NOIP怎么办啊?Mr.Lin的题出好了,个人认为比较良(hei)心,希望以后做到这套题的人不要骂我吧233。
题解就贴在这里好了:
T1 K-D tree裸题,本蒟蒻刚学会K-D tree想练练手,于是和暴力大战了一天之后,终于把std写出来了QAQ
题解是直接建KD树,因为我加强了数据,所以表示我们要重构这棵树(不重构过了得真是强orz我把我没有重构的跑直接RE..),判圆我们可以用欧几里得距离评估,是一个很棒的东西,感谢Claris~
欧几里得距离评估:
max((XpMaxX)2,(XpMinX)2)+max((YpMaxY)2,(YpMinY)2)R2
此时该矩形区域被圆完全包含
max(max(XpMaxX,pMinXX),0)2+max(max(YpMaxY,pMinYY),0)2>R2
此时该矩形区域与圆无交集
根据这个来更新就好了~

T2 字符串水题,就是求一个字符串的最小表达,我们记录 i 为当前开始的最优位置,j 为我们待选择的位置,并设置 k 为最小的 x|[s[i+x]s[j+x]] 我们可以知道,当刚好 ks.length() 时是最优答案,所以我们可以比较 s[i+k]s[j+k] 的大小。
分情况讨论 s[i+k]>s[j+k] 时,我们用 j 来更新答案,并看看 j 的下一个位置在哪里,显然 j=max(j,i+k)
否则的话 则当前这一段长度为 k 的区间我们都不能作为开头,因为并不优,所以 j=j+k+1

题解就那么多,不懂得看程序吧,包里应该有ovo~

另外贴一道NOIP2009的题解,蒟蒻NOIP题都玩不溜啊

#include<cmath>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define N 50000#define ll long longll prime[N+10],pcnt;ll p[N],a0,a1,b0,b1;ll cnt[N];ll num[3];bool flag[N+10];void pre(){    for (ll i = 2 ; i <= N ; ++i)    {    if (!flag[i]) prime[++pcnt] = i;    for (ll j = 1 ; j <= pcnt && i * prime[j] <= N ; ++j)    {        flag[i*prime[j]] = 1;        if (i % prime[j] == 0) break;    }    }}void factor(ll x){    ll m = sqrt(x);    for (int i = 1 ; i <= pcnt && prime[i] <= m ; ++i)    {    if (x % prime[i] == 0) p[++p[0]] = prime[i],cnt[p[0]]++,x /= prime[i];    while (x % prime[i] == 0)    {        cnt[p[0]]++;        x /= prime[i];    }    if (x == 1) break;    }    if (x ^ 1) p[++p[0]] = x,cnt[p[0]]++;}int main(){#ifdef VictorXie    freopen("son.in","r",stdin);#endif    ll t;    pre();    scanf("%lld",&t);    while (t--)    {    ll ans = 1;    bool flag = 0;    scanf("%lld%lld%lld%lld",&a0,&a1,&b0,&b1);    memset(p,0,sizeof(p));    memset(cnt,0,sizeof(cnt));    if (b1 % a1) {puts("0");continue;}    num[0] = b1/b0,num[1] = b1/a1,num[2] = a0/a1;    factor(num[1]);    for (int i = 1 ; i <= p[0] ; ++i)        if (num[2] % p[i] == 0) cnt[i] = 0;    for (int i = 1 ; i <= p[0] ; ++i)        if (num[0] % p[i] == 0)        if (!cnt[i]) {flag = 1;break;}        else cnt[i] = 0;    if (flag) {puts("0");continue;}    for (int i = 1 ; i <= p[0] ; ++i)        ans *= (cnt[i]+1);    printf("%lld\n",ans);    }}
0 0