# 【Author ： DS && MZ】2012 金华网络预赛 Chapter 2

22 篇文章 0 订阅

1008 数论

Operator 1 ： 用容斥原理计算出[l , r] 里面与p互质的数的和。 遍历前面的Operator 2 操作，如果在区间内则修改。

Operator 2 ： 将操作放在Vector里面，并用一个Map记录x

const LL PRIMERANGE = 400001;
int prime[PRIMERANGE + 1];
int getPrime()
{
memset (prime, 0, sizeof (int) * (PRIMERANGE + 1));
for (int i = 2; i <= PRIMERANGE; i++)
{
if (!prime[i]) prime[++prime[0]] = i;
for (int j = 1; j <= prime[0] && prime[j] <= PRIMERANGE / i; j++)
{
prime[prime[j]*i] = 1;
if (i % prime[j] == 0) break;
}
}
return prime[0];
}

int factor[100][3], facCnt;
int getFactors(int x)
{
facCnt = 0;
int tmp = x;
for(int i = 1; prime[i] <= tmp / prime[i]; i++)
{
factor[facCnt][1] = 1, factor[facCnt][2] = 0;
if(tmp % prime[i] == 0)
factor[facCnt][0] = prime[i];
while(tmp % prime[i] == 0)
factor[facCnt][2]++, factor[facCnt][1] *= prime[i], tmp /= prime[i];
if(factor[facCnt][1] > 1) facCnt++;
}
if(tmp != 1)
factor[facCnt][0] = tmp, factor[facCnt][1] = tmp, factor[facCnt++][2] = 1;
return facCnt;
}
LL getmz(LL nn , LL pp){
LL res = nn / pp;
res = res * (res + 1LL) / 2LL;
return res * pp;
}
LL getds(LL nn , LL pp){
getFactors(pp);
LL ans = 0;
LL alll = 1LL << facCnt;
for (int i = 0 ; i < alll ; ++i){
int temp = 0 ; LL tempsum = 1;
int ii = i;
for (int j = 0 ; j < facCnt && ii ; ++j){
if (ii & 1){
temp ++;
tempsum *= factor[j][0];
}
ii >>= 1;
}
//cout << tempsum << endl;
if (temp & 1) ans-=getmz( nn , tempsum);
else ans+= getmz(nn ,tempsum);
}
return ans;
}
int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}
int n , m;
map<LL , LL> mem;
map<int , int> :: iterator iter;
vector< pair<int , LL> > mz;
void solve(){
mz.clear();
mem.clear();
scanf("%d%d" , &n, &m);
while (m--){
int op , x , y , z;
scanf("%d",&op);
if (op == 2){
scanf("%d%d" , &x, &y);
mz.push_back(make_pair(x , y));
mem[x] = mz.size() - 1;
}
else{
scanf("%d%d%d" , &x , &y , &z);
LL ans = getds(y , z) - getds(x - 1, z);
for (int i = 0 ; i < mz.size();++i){
if (mem[mz[i].first] != i) continue;
if (x <= mz[i].first && mz[i].first <=y){
LL now = mz[i].first;
if (gcd(now , z) == 1) ans -= now;
now = mz[i].second;
if (gcd(now , z) == 1) ans += now;
}
}
printf("%I64d\n",ans);
}
}
}
int main(){
int _;
getPrime();
cin >> _;
while (_--) solve();
}

1010 裸LCA

Trick ：

root的兄弟有一个 ； 公共祖先的定义不同

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <cstring>
#include <cmath>
#define N 30100
#define M 1010
#define MP make_pair
#define PB push_back

using namespace std;
map<string,int> hash;
int n;
struct cong
{
int gen;
string name;
int fa;
int id;
cong(){}
cong (int a,string ss)
{
gen = a;
name = ss;
}
}s[N];
int r[N];
vector<int> son[N];
void init()
{
hash.clear();
memset(r,0,sizeof(r));
for (int i=0;i<=n;i++) son[i].clear();
}
cong deal(char ss[M])
{
int now = 0;
int len = strlen(ss);
int temp = 0;
while (now<len)
{
if (ss[now++]=='.') temp++;
else break;
}
string tt = "";
for (int i=now-1;i<len;i++) tt+=ss[i];
return cong(temp,tt);
}
void dfs(int k)
{
//cout << "k = " << k << endl;
for (int i=1;i<=s[k].gen;i++) printf("%c",'.');
printf("%s\n",s[k].name.c_str());
for (int i=0;i<son[k].size();i++)
{
dfs(son[k][i]);
}
}
#define MAXN 100300
#define MAXL 20
struct ST
{
int dat, loc;
ST(int x, int y)
{
dat = x, loc = y;
}
ST(){}
}st[MAXN][MAXL];
int num[MAXN], p2[MAXL], h[MAXN], firstapp[MAXN];
void Format_ST()
{
memset(st, 0, sizeof(st));
p2[0] = 1;
for (int i = 1; i < MAXL; ++i) p2[i] = p2[i - 1] * 2;
for (int i = 1; i <= n; ++i) st[i][0] = ST(h[i], num[i]);
for (int j = 1, p = 1; j < MAXL; ++j, p *= 2)
for (int i = 1; i <= n - p * 2 + 1; ++i)
if (st[i][j - 1].dat > st[i + p][j - 1].dat) st[i][j] = st[i][j - 1];
else st[i][j] = st[i + p][j - 1];
}
ST RMQ(int s, int t)
{
int l = (int)(log((double)(t - s + 1)) / log(2.0) + 1e-6);
if (st[s][l].dat > st[t - p2[l] + 1][l].dat) return st[s][l];
else return st[t - p2[l] + 1][l];
}
void make(int v, int deep)
{
h[++n] = -deep;
num[n] = v;
for (int i = 0; i < son[v].size(); i++)
{
int y  =son[v][i];
make(y, deep + 1);
h[++n] = -deep;
num[n] = v;
}
}
bool cmp(int x,int y)
{
return s[x].name<s[y].name;
}

int main()
{
freopen("in.in","r",stdin);
char ss[M],tt[M];
while (scanf("%d\n",&n),n)
{
init();
r[0] = 1;
scanf("%s",ss);
s[1] = cong(0,ss);
hash[ss] = 1;
s[1].fa = 0;
s[1].id = 1;
for (int i=2;i<=n;i++)
{
scanf("%s",ss);
s[i] = deal(ss);
s[i].id = i;
hash[s[i].name] = i;
s[i].fa = r[s[i].gen-1];
r[s[i].gen] = i;
son[s[i].fa].PB(i);
}
for (int i=1;i<=n;i++)
{
sort(son[i].begin(),son[i].end(),cmp);
}

//LCA
n=0;
make(1, 0);
memset(firstapp,0,sizeof(firstapp));
for (int i = 1; i <= n; ++i)
if (!firstapp[num[i]]) firstapp[num[i]] = i;
Format_ST();
int m;
scanf("%d\n",&m);
while (m--)
{
scanf("%s",ss);
if (ss[0]=='L')
{
dfs(1);
}
else if (ss[0]=='b')
{
scanf("%s",ss);
if (hash[ss]==1) printf("1\n");
else
{
int fa = s[hash[ss]].fa;
printf("%d\n",son[fa].size());
}
}
else
{
scanf("%s%s",ss,tt);
int x = hash[ss];
int y = hash[tt];
int sx = firstapp[x], sy = firstapp[y];
if (sx>sy) swap(sx,sy);
int temp = RMQ(sx, sy).loc;
if (temp==x || temp==y) printf("%s\n",s[s[temp].fa].name.c_str());
else printf("%s\n", s[temp].name.c_str());
}
}
}
return 0;
}



• 0
点赞
• 0
评论
• 0
收藏
• 打赏
• 扫一扫，分享海报

05-31 6485

06-06 6705
12-22 3418
12-27 1万+
05-22 1万+
06-03 9859

ACM的记忆

¥2 ¥4 ¥6 ¥10 ¥20

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、C币套餐、付费专栏及课程。