cf330 594D — REQ

原创 2015年11月20日 21:39:40

题目描述:

题解:

其实是一道很躶的题目。关键是求出L到R之间的质数的出现情况。
想到一种莫队的算法,但是可能会超时。
因此有下面一种很实用的方法。对于离线查询,我们相当于可以固定左端点,那么其实对于质数p,就是从l之后的第一个出现p的位置是关键位置。我们用线段树来区间修改。最开始预处理所有的结果为正确的。然后随着l的平移,对于删掉的左边的数,它的质数应从l到下一个l-1之间都要去除这个质数的影响。搞一搞就行了

重点:

关键是离线相当于可以固定l。 然后我们对于固定的l来说,我们一个p只需要一个关键的位置,就可以描述。
学习了金爷两个姿势。
1。搞一个数的质数。
2。vec【i】。back 和 front。
3。另外学一下树状数组把。。。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>

#define lrt (rt<<1)
#define rrt ((rt<<1)|1)
#define mid ((l+r)/2)

using namespace std;

typedef long long ll;

const int maxn  = 1e6 + 100;
const int MAXNODE = maxn;
const int M = 1e9 + 7.1;
const int MAXVAL = 1e6 + 0.5;

struct node
{
    int l, r, id;
    node(int _l = 0, int _r = 0, int _id = 0)
    {
        l = _l;
        r = _r;
        id = _id;
    }
};

int n, a[maxn], mul[maxn], tree[maxn], cur[maxn], p[maxn], pn, vis[maxn], qn, rev[maxn], ans[maxn], bo[maxn];
node q[maxn];
vector<int> vec[maxn];
vector<int> num[maxn];

int mult(int a, int b)
{
    int c = (ll)a * (ll)b % M;
    return c;
}

int pow_mod(int x, int n)
{
    int res = 1;
    int tmp = x % M;
    while(n)
    {
        if(n&1)
            res = mult(res, tmp);
        tmp = mult(tmp, tmp);
        n >>= 1;
    }
    return res;
}
int getRev(int x)
{
    return pow_mod(x, M - 2);
}

void prime()
{
    memset(vis, 0, sizeof(vis));
    pn = 0;
    for(int i = 2; i <= MAXVAL; i++)
    {
        if(vis[i] == 0)
        {
            p[pn] = i;
            pn++;
            vis[i] = 1;
            bo[i] = i;
        }
        for(int j = 0; j < pn && i * p[j] <= MAXVAL; j++)
        {
            bo[i * p[j]] = p[j];
            vis[i * p[j]] = 1;
            if(i % p[j] == 0)
                break;
        }
    }
}

void pushDown(int rt)
{
    if(tree[rt] == 1)
        return;
    tree[lrt] = mult(tree[lrt], tree[rt]);
    tree[rrt] = mult(tree[rrt], tree[rt]);
    tree[rt] = 1;
}

void change(int L, int R, int key, int rt, int l, int r)
{
    if(L <= l && R >= r)
    {
        tree[rt] = mult(tree[rt], key);
        return;
    }
    pushDown(rt);
    if(L <= mid)
        change(L, R, key, lrt, l, mid);
    if(R >= mid + 1)
        change(L, R, key, rrt, mid + 1, r);
}
int query(int pos, int rt, int l, int r)
{
    if(r == l && r == pos)
    {
        return tree[rt];
    }
    pushDown(rt);
    if(pos <= mid)
        return query(pos, lrt, l, mid);
    else
        return query(pos, rrt, mid + 1, r);
}
void dfs_init(int rt, int l, int r)
{
    if(l == r)
    {
        tree[rt] = 1;
        return;
    }
    tree[rt] = 1;
    dfs_init(lrt, l, mid);
    dfs_init(rrt, mid + 1, r);
}

void solve()
{
    for(int i = 0; i <= MAXVAL; i++)
        vec[i].clear();
    mul[0] = 1;
    for(int i = 1; i <= n; i++)
    {
        mul[i] = mult(mul[i-1], a[i]);
        num[i].clear();
        int x = a[i];
        while(x != 1)
        {
            int t = bo[x];
            vec[t].push_back(i);
            num[i].push_back(t);
            while(x % t == 0)
                x /= t;
        }
    }
    dfs_init(1, 1, n);
    for(int i = 2; i <= MAXVAL; i++)
    {
        if(vec[i].size() >= 1)
            change(vec[i][0], n, (ll)(i-1) * (ll)rev[i] % M, 1, 1, n);
        cur[i] = 0;
    }
    int tl = 1;
    for(int i = 0; i < qn; i++)
    {
        while(tl < q[i].l)
        {
            for(int j = 0; j < num[tl].size(); j++)
            {
                int x = num[tl][j], tr;
                if(cur[x] + 1 >= vec[x].size())
                {
                    cur[x]++;
                    tr = n+1;
                }
                else
                {
                    tr = vec[x][cur[x] + 1];
                    cur[x]++;
                }
                change(tl + 1, tr - 1, (ll)x * (ll)rev[x-1] % M, 1, 1, n);
            }
            tl++;
        }
        int res = (ll)mul[q[i].r] * (ll)getRev(mul[q[i].l - 1]) % M * (ll)query(q[i].r, 1, 1, n) % M;
        ans[q[i].id] = res;
    }
    for(int i = 0; i < qn; i++)
    {
        printf("%d\n", ans[i]);
    }
}
bool cmp(node a, node b)
{
    return a.l < b.l;
}

int main()
{
    freopen("Din.txt", "r", stdin);
    prime();
    for(int i = 1; i <= MAXVAL; i++)
        rev[i] = getRev(i);
    while(scanf("%d", &n) != EOF)
    {
        for(int i = 1; i <= n; i++)
            scanf("%d", &a[i]);
        scanf("%d", &qn);
        for(int i = 0; i < qn; i++)
        {
            scanf("%d%d", &q[i].l, &q[i].r);
            q[i].id = i;
        }
        sort(q, q + qn, cmp);
        solve();
    }
    return 0;
}

CodeForces 594D REQ(树状数组)

分析:第一反应是用莫队来写,这样每次查询的复杂度是o(n∗n−−√)o(n*\sqrt{n}),设MM是a[i]a[i]中最大的数,那么每一次修改的复杂度是o(logM)o(logM),那么总的复杂度...
  • u014610830
  • u014610830
  • 2015年11月27日 12:38
  • 478

CodeForces 594D REQ(树状数组+欧拉函数)

题意:给出一个序列,有m个询问,每次询问要求回答一个区间内所有数的乘积的欧拉函数。 思路:这道题看上去像是一个莫队,但是莫队的时间复杂度为O(n∗sqrt(n)∗k)O(n*sqrt(n)*k),其...
  • u014664226
  • u014664226
  • 2016年05月18日 14:23
  • 317

req

req.params.xxxxx 从path中的变量 req.query.xxxxx 从get中的?xxxx=中 req.body.xxxxx 从post中的变量 ...
  • RevolCat
  • RevolCat
  • 2016年08月21日 14:09
  • 179

#216. REQ

讲道理刚看完题目就听到题解了233
  • wamach
  • wamach
  • 2017年06月11日 19:22
  • 97

CentOS 没有root权限下Caffe 安装的小问题

CentOS 下Caffe 安装的小问题今天需要在一台CentOS服务器上安装Caffe。因为之前一直在用Ubuntu, 而且这台服务器没有root权限,因此遇到了一些小问题,最终总算解决了,记录一下...
  • zhzhanp
  • zhzhanp
  • 2016年02月22日 21:31
  • 1984

Express框架req,res常用属性与方法

var express = require('express'); var bodyParser = require('body-parser'); var app = express(); //js...
  • Nick_php
  • Nick_php
  • 2016年08月23日 00:04
  • 3325

HttpServletRequest req 的用法

后台的一部分 public void modelParam(String parakey, HttpServletRequest req) { ModelParam mp = modelParam...
  • zyk2015
  • zyk2015
  • 2016年04月21日 17:09
  • 231

nodejs -- express 之 req(响应)官方API 翻译

【 翻译不易,谢谢批评指正 】 请求 该req对象表示的HTTP请求,并且具有用于请求查询字符串,参数,身体,HTTP报头,等等性质。在本文档按照惯例,该对象总是被称为req(和HTTP响应res...
  • qq_35085956
  • qq_35085956
  • 2017年04月07日 11:21
  • 2249

openssl req 证书请求及自签名证书

opensl req> 介绍 openssl req 用于生成证书请求,以让第三方权威机构CA来签发,生成我们需要的证书。req 命令也可以调用x509命令,以进行格式转换及显示证书文件中的...
  • fym0121
  • fym0121
  • 2012年09月18日 16:34
  • 22296

zeromq源代码分析6-2------REQ和REP

本文我们讲一下req和rep这对zeromq的socket。这是一个经典的Request-Reply的例子。
  • kaka11
  • kaka11
  • 2011年07月22日 17:19
  • 9841
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:cf330 594D — REQ
举报原因:
原因补充:

(最多只允许输入30个字)