惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

罗磊的独立博客
L
LangChain Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
H
Hackread – Cybersecurity News, Data Breaches, AI and More
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
M
MIT News - Artificial intelligence
N
Netflix TechBlog - Medium
Vercel News
Vercel News
D
DataBreaches.Net
Microsoft Azure Blog
Microsoft Azure Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
The Cloudflare Blog
U
Unit 42
阮一峰的网络日志
阮一峰的网络日志
Blog — PlanetScale
Blog — PlanetScale
Cloudbric
Cloudbric
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Microsoft Security Blog
Microsoft Security Blog
月光博客
月光博客
I
InfoQ
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Hugging Face - Blog
Hugging Face - Blog
Security Latest
Security Latest
T
Threatpost
GbyAI
GbyAI
K
Kaspersky official blog
S
SegmentFault 最新的问题
Schneier on Security
Schneier on Security
V
V2EX
W
WeLiveSecurity
Recorded Future
Recorded Future
WordPress大学
WordPress大学
L
LINUX DO - 最新话题
O
OpenAI News
Y
Y Combinator Blog
Google DeepMind News
Google DeepMind News
The Last Watchdog
The Last Watchdog
有赞技术团队
有赞技术团队
Attack and Defense Labs
Attack and Defense Labs
N
News | PayPal Newsroom
H
Help Net Security
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Webroot Blog
Webroot Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
T
Troy Hunt's Blog
腾讯CDC
Scott Helme
Scott Helme
P
Privacy & Cybersecurity Law Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
E
Exploit-DB.com RSS Feed

博客园 - zy_nic

.. emacs的c++mode contest contest 我的2-sat模板 Solution to GCJ Practice Contest Problem C, Cycles 约瑟夫问题的数学方法 我的模板 图的应用 pku3411 今天的比赛 关于建图的 死老鼠安装成功 pku3141 先帖个题目上来 hnu 11028 hnu 11015 joj 儿死三八 pku 1273
SRM 424 div1 900 ProductOfPrices 翻译
zy_nic · 2008-11-19 · via 博客园 - zy_nic

为了解决这样的问题,我们需要关于一个整型数组A[1..N]的数据结构,它支持这样的操作,起初,数组中的元素都是0,而且这样的数据结构支持下面两种操作:

1.更新A[pos] = A[pos] + value (其中value,pos是任意给定的,且可能为负值)

2.计算sum(A, l, r) = A[l]+A[l+1]+A[l+2]+...+A[r-1]+A[r] (其中l, r是任意给定的)

我们需要这样的操作都在O(log N)的时间内完成。能够实现这样操作的数据结构是 Binary Idexed Trees (BIT)。 

在我们的解决方案中我们需要两个树状数组(BIT), 下标从1..L。其中第一个叫做cnt, cnt[i] 是当前种在i这个位置中树的个数(我们增加将所有树的下标增加1,使得所有的下标在1..L内)。第二个数组叫做dst, dst[i] = cnt[i]*i。换句话说,dst[i]是所有种在位置i的树的距离和。

假设我们要在x[i]处种一棵树, 并且想要尽快计算出他的price。我们有CL=sum(cnt, 1, x[i]-1) 棵树在x[i]的左边。每个种在x0处的树距离第i棵树的距离是x[i]-x0。所以左边所有树到第i棵树的距离和就是 CL*x[i]-sum(all x0) = CL*x[i]-sum(dst, 1, x[i]-1)。同样的有CR=sum(cnt, x[i]+1, L)棵树在第i棵树的右边,他们到第i棵树的距离和是 sum(dst, x[i]+1, L)-CR*x[i]。所以总的price 可以由下式计算:


 price = x[i] * (sum(cnt, 1, x[i]-1- sum(cnt, x[i]+1, L)) +
        sum(dst, x[i]
+1, L) - sum(dst, 1, x[i]-1

计算好price后我们只需要更新cnt, dst数组, cnt[x[i]]=cnt[x[i]]+1, dst[x[i]]=dst[x[i]]+x[i]


class ProductOfPrices {
public:
    
int product(intintintintint);
};
int L;
int64 cnt[
200001], dst[200001];
int64 x[
200001];
void add(int64 a[], int64 i, int64 x)
{
    
while (i <= L)
    {
        a[i] 
+= x;
        i 
|= i-1;
        i
++;
    }
}
int64 getSum(int64 a[], int64 i)
{
    int64 res 
= 0;
    
while (i > 0)
    {
        res 
+= a[i];
        i 
&=i-1;
    }
    
return res;
}
int64 getSum(int64 a[], int64 i, int64 j)
{
    
if (j >= i)
        
return getSum(a, j) - getSum(a, i-1);
    
else
        
return 0;
}
int ProductOfPrices::product(int N, int l, int X0, int A, int B) 
{
    L 
= l;
    x[
0= X0%L;
    
for (int i = 1; i < N; i++)
        x[i] 
= ((int64(x[i-1])*int64(A))+int64(B)) % int64(L);
    memset(cnt, 
0sizeof(cnt));
    memset(dst, 
0sizeof(dst));
    add(cnt, x[
0]+11);
    add(dst, x[
0]+1, x[0]+1);
    int64 res 
= 1;
    
for (int i = 1; i < N; i++)
    {
        int64 price 
= (x[i]+1* getSum(cnt, 1, x[i]) - getSum(dst, 1, x[i])
                       
+ getSum(dst, x[i]+1, L) - getSum(cnt, x[i]+1, L) * (x[i]+1);
        price 
%= 1000000007;
        res 
= (res * price) % 1000000007;
        add(cnt, x[i]
+11);
        add(dst, x[i]
+1, x[i]+1);
    }
return (int)res;